/*
 * member theme — portal-local (legacy generic-named). Owned by /build-theme.
 * Changelog:
 * 2026-08-21 (IN-PLACE, newest) — SITE-WIDE STANDARDISATION PASS (owner-approved, 4 rulings:
 *   homepage FAQ form site-wide, unified product card w/ coral price, pill button family h-12,
 *   auth pages scaled to industry size). This file's part:
 *   VALUES CHANGED (3): --input-label-size / --input-text-size / --input-placeholder-size
 *     17px -> 16px. Auth + form inputs were the outlier at 17; 16 is the industry norm the
 *     owner approved. Ripple: every input site-wide renders 1px smaller — intended.
 *   NEW NON-CANON TOKENS (9), extension block at the bottom: --hero-scrim-gradient,
 *     --hero-scrim-gradient-strong, --hero-text-shadow, --shadow-modal, --shadow-panel,
 *     --toast-warning-bg, --toast-warning-border, --toast-error-border, --loader-size.
 *     Each replaces raw rgba()/#hex literals repeated across pages (hero scrims x8, modal
 *     shadows x7, auth card shadow x4, toast palette in head_v*). Colour values are byte-for-byte
 *     what the pages rendered before, EXCEPT --toast-error-border: was Metronic pink #d62a64 on
 *     an #DC3B2E toast (old-template relic), now #C33427 (darker of the brand error red).
 * 2026-08-20 (IN-PLACE, after the checkout entry) — 7 TOKENS RESTORED FROM THE HOME BODY RESKIN.
 *   Not new work: the Home pass ran earlier the same day, its edits to this file sat unmerged
 *   while two other sessions (Blog, then Checkout) rewrote it, and this entry brings back only the
 *   parts that were ADDITIVE — --color-star-gold, --color-whatsapp, --color-whatsapp-bg,
 *   --shadow-lift, --border-on-dark, --text-on-dark-muted, --surface-on-dark-subtle. See the
 *   extension block at the bottom for what each one is for.
 *   WHAT WAS DELIBERATELY NOT RESTORED, because doing so would have undone committed work with no
 *   error anywhere: the Home version of this file predates both later sessions, so replaying it
 *   wholesale would have DELETED 4 tokens now in use (--color-brand-primary-deep,
 *   --color-brand-primary-hover, --color-text-neutral, --shadow-panel-hover — all consumed by
 *   _blog-card.php / blog.php / blog-detail.php, where a missing var() renders as nothing) and
 *   reverted 4 values (--color-text-link back to #F06353, undoing an owner design-wins call;
 *   --color-brand-primary-dark, --shadow-brand, --shadow-card-hover). Committed values were kept
 *   in every case. ONE STILL OPEN for the owner: --color-brand-primary-dark is #D94A3A here and
 *   the Home pass read the same coral as #DC3B2E. Both were documented as design-sourced.
 * 2026-08-20 (IN-PLACE) — CHECKOUT DESIGN ALIGNMENT. Driven by /page-reskin LAW 1 for
 *   member/checkout.php against "GoTasty Checkout (standalone) (1).html". Owner decision on every
 *   row: DESIGN WINS. Path chosen: values-only + inject missing CANONICAL tokens (not adopt-canon,
 *   not a prefixed extension block).
 *
 *   VALUES CHANGED (2):
 *     --shadow-sm            0 2px 6px rgba(42,45,65,0.08) -> 0 1px 3px rgba(42,45,65,0.07)
 *     --color-bg-pink-subtle #FEF3F1 -> #FEF7F5   PORTAL-WIDE: 24 uses across 8 member pages.
 *       Owner approved the ripple. The five OTHER tokens holding #FEF3F1 (--sixth-color,
 *       --secondary-bg-color, --listing-row-child-primary-color,
 *       --listing-row-child-secondary-color, --color-brand-blush) are UNCHANGED — only the
 *       selected-surface role moved.
 *
 *   CANONICAL TOKENS INJECTED (3) — present in templates/theme-template.css, absent here. This
 *   file carries 75 of the 126 canon tokens; these three are now 78. The other 48 stay missing
 *   (adopting the full schema is a Refactor + major bump, deliberately not done today):
 *     --border-radius-full     9999px    canon default, exact design match
 *     --card-border-radius     16px      canon default var(--border-radius-md); design wins
 *     --secondary-border-color #EDEDF1   canon default #F1F2F4; design wins
 *
 *   NEW NON-CANON TOKENS (2) — no canonical slot covers these roles, and the usual
 *   soft-fallback var(--x,#hex) is NOT available: /page-reskin v1.12.0's step-9b gate greps page
 *   markup for raw hex and blocks on it, so an uncovered role must become a real token or the
 *   page cannot be built at all. Named for this file's own conventions, not a new prefix:
 *     --color-text-label   #595960   uppercase field labels
 *     --radius-option-row  12px      selectable option rows
 *
 *   NOT TOUCHED, on purpose:
 *     --border-radius-lg  stays 15px — ZERO consumers in any member page, so the design's 16px card
 *       radius went to the canon --card-border-radius slot instead of retuning a shared step.
 *     --btn-border-radius stays 30px — the design's pills are served by --border-radius-full.
 *     FPX #14498F and GrabPay #00B14F were requested as tokens and are NOT added: the page renders
 *       payment marks as images (/images/payment/fpx.webp), so FPX needs no colour, and GrabPay
 *       needs an ASSET (page-reskin handoff fh-1), not a token.
 * 2026-08-20 (IN-PLACE, latest+1) — 5 MORE TOKENS, same GoTasty Blog handoff, all read off its
 *   own :root and :hover rules rather than derived:
 *     --color-brand-primary-hover NEW #E14A39               <- design --brand-hover (button bg)
 *     --shadow-card               NEW 0 1px 3px   rgba(42,45,65,.06)
 *     --shadow-card-hover         NEW 0 14px 34px rgba(42,45,65,.13)
 *     --shadow-panel-hover        NEW 0 16px 40px rgba(42,45,65,.13)
 *     --shadow-brand              NEW 0 8px 24px  rgba(240,99,83,.34)
 *   and it matches none of the design's four, so _blog-card.php had been carrying a hardcoded
 *   rgba(28,34,50,0.22) hover shadow since v1.0.1. The card/panel hover pair is deliberately NOT
 *   collapsed into one token — the design uses 14/34 on a grid card and 16/40 on the wide hero.
 * 2026-08-20 (IN-PLACE, latest) — 1 TOKEN ADDED, 2 VALUES CORRECTED, from the GoTasty Blog
 *   listing handoff (spec/design-src/blog.design.html). All three are values the design DECLARES
 *   in its own :root, so none is derived:
 *     --color-text-neutral      NEW      #595960   <- design --neutral-600 (card category pill)
 *     --color-text-link         #F06353 -> #E14A39 <- design --coral-600 (owner: design-wins)
 *     --color-brand-blush-deep  #FDE0DB -> #F8C3B9 <- design --coral-200 (was derived)
 *   NOT added: #BE3A2B. It arrived minutes earlier in this same file as
 *   --color-brand-primary-deep, from the Blog ARTICLE handoff (blog-detail.php) — same design
 *   --coral-700, same pale-pill-on-blush role. A second name for one hex is how a catalog rots,
 *   so the blog LISTING's featured pill reuses that token. Worth knowing: two sessions were
 *   editing this file at once; this entry was written against md5 93ca7c60 and reuses rather
 *   than re-declares.
 * 2026-08-20 (IN-PLACE, later) — 4 RUNGS ADDED TO THE --fs-* LADDER: --fs-12, --fs-32, --fs-36,
 *   --fs-42. Not a new category — the ladder is by construction "raw px x scale", named for its
 *   base, and these are the steps the pages needed once their hardcoded sizes became tokens.
 *   --fs-19 and --fs-48 were added in the same pass and REMOVED again in the one below: the
 *   nearest-RENDERED remap left them with zero consumers, and a token nothing reads is a trap for
 *   the next person deciding what the ladder means.
 *
 * 2026-08-20 (IN-PLACE, last) — --font-scale 1.12 -> 1, AND THE LADDER IS NOW HONEST.
 *   Owner call, and it settles a problem the two previous attempts at this only moved around.
 *   Every size token is calc(base * --font-scale). With the scale at 1.12 no token could render an
 *   integer: --md-text-size read "15px" in the source and painted 16.8px. Mapping a page's
 *   hardcoded 15px to it grew the type 12%; mapping instead by nearest RENDERED size kept the
 *   pixels but made every name lie about its own value (a 14px site pointing at --fs-12). Both are
 *   symptoms of the same thing — a multiplier between the declared number and the painted one.
 *   At --font-scale: 1 the declared number IS the painted one. --md-text-size is 15px, full stop.
 *   All 26 distinct sizes the pages use now hit a rung exactly, with --fs-19 and --fs-48 restored
 *   (they were deleted an hour earlier when the nearest-rendered map left them unused).
 *   WHAT MOVES: ~373 references that were ALREADY tokens before this rebrand pass render 12%
 *   smaller than they did yesterday — a --sm-text-size site goes 14.56px -> 13px. That is the
 *   whole cost, it is portal-wide, and it is worth eyeballing on the form-dense pages (checkout,
 *   cart, sign-up). Nothing that was a hardcoded px changes at all: those now paint the exact
 *   number their author wrote.
 *   The scale mechanism is KEPT, not removed — it is still the one knob for resizing the portal.
 *   If the portal should be bigger, raise the BASE values so the numbers stay honest; do not
 *   reintroduce a multiplier.
 * 2026-08-20 (IN-PLACE) — 13 TOKENS ADDED, 6 VALUES CHANGED. Driven by the owner rule stated this
 *   day: values come from the theme, 100% no hardcoded colour/font at page level. The GoTasty
 *   chrome rebuild (homepageHeader_v1.0.18 / homepageFooter_v1.0.15) had 17 rendered literals in
 *   its markup — raw rgba() inside Tailwind arbitrary values, bg-white/NN opacity utilities, and
 *   var(--name,#hex) soft-fallbacks. A fallback hex is still a hardcoded colour sitting in a page
 *   file; it just hides behind a token name. Every one of them is now a token here and the markup
 *   references it with NO fallback. Filename kept: additive + value-only, so head_v1.0.11's <link>
 *   and its filemtime cache-bust need no edit — same reasoning as the 2026-08-19 entry below.
 *
 *   SOURCE. Values are not invented. The 2026-08-20 design handoff ("GoTasty Home (standalone)
 *   .html") ships a full :root design system, and every value below is one of its declared tokens:
 *       --color-bg-subtle        #F8F8FA          <- design --neutral-50  / --surface-page
 *       --color-text-faint       #A6A6AE          <- design --neutral-400
 *       --error-color            #DC3B2E          <- design --red-500     ("error / sold out")
 *       --warning-color          #F2A33C          <- design --amber-500
 *       --success-color          #2E9E5B          <- design --green-500
 *       --input-placeholder-color #A6A6AE         <- design --neutral-400 (its placeholder colour)
 *       --surface-on-dark(-hover)                 <- design --border-on-dark family
 *       --overlay-bg-color                        <- the design drawer's own scrim
 *       --shadow-sm / -dropdown / -drawer         <- SiteHeader's own box-shadow values
 *       --radius-panel / --radius-menu-item       <- SiteHeader's dropdown + menu-item radii
 *
 *   ADDED (13): --color-bg-subtle, --color-text-faint, --radius-panel, --radius-menu-item,
 *     --footer-border-color, --surface-on-dark, --surface-on-dark-hover, --overlay-bg-color,
 *     --overlay-strong-bg-color, --focus-ring-color, --shadow-sm, --shadow-dropdown, --shadow-drawer.
 *
 *   NO --color-text-danger, deliberately. The chrome's Sign Out needs the design's red and so does
 *   validation; the design has ONE --red-500 for both. Minting a danger token would have put the
 *   same value in two slots, and the first person to re-shade one would leave the other behind.
 *   Sign Out uses --color-text-error.
 *
 *   CHANGED (6) — VALUES ONLY, no token renamed or removed, so every existing consumer keeps
 *   working and simply picks the new colour up:
 *     --error-color            #FD397A -> #DC3B2E   (11 live consumers)
 *     --warning-color          #E0A800 -> #F2A33C   (4)
 *     --success-color          #00B900 -> #2E9E5B   (4)
 *     --color-text-error       #FD397A -> #DC3B2E   (3)
 *     --color-text-success     #00B900 -> #2E9E5B   (2)
 *     --input-placeholder-color #d6d6d6 -> #A6A6AE  (contact-us.php x3 + the header search)
 *   ⚠️ These repaint validation messages, toasts and status badges across the member portal.
 *   #FD397A was a pink and #DC3B2E is a red — the biggest visible shift of the six. The old
 *   placeholder #d6d6d6 also failed contrast against white; #A6A6AE is the design's own value.
 *   Worth eyeballing a failed form submit and a toast after deploying.
 *
 *   NOT DONE, on purpose: --badge-*-bg/text (11 tokens) still hold their 2026-07-03 values. They
 *   are a self-consistent Tailwind-palette set with their own bg/text/border trios, and the design
 *   ships no badge system to map them onto. Re-colouring them from the four semantic-500 values
 *   would be invention, not translation.
 * 2026-08-19 (later, IN-PLACE) — MRFLOWER FACES RETIRED. The type system is now exactly two
 *   families, both GoTasty: Poppins (display) and Nunito Sans (body).
 *     - DELETED 5 @font-face blocks: Montserrat 400/500/600/700 and Quinstory 100-900. The entry
 *       below says they were "DELIBERATELY KEPT" because 57 the Quinstory family literal references depended
 *       on them; that dependency is gone. Every hardcoded family reference across the portal was
 *       converted first (73 of them: 29 Quinstory -> font-display, 40 a hardcoded Poppins family literal ->
 *       font-display, 4 font-['Nunito_Sans',...] -> font-sans), verified to zero with comments
 *       stripped, and ONLY THEN were the faces removed. That order matters: dropping the faces
 *       while a reference survived would not have shown the old font, it would have fallen through
 *       to Georgia/serif — a silent, uglier regression than the one being fixed.
 *     - DELETED the files too: css/fonts/Montserrat/ (864KB, 8 files) and css/fonts/Quinstory/
 *       (48KB, 2 files). ~912KB off every deploy. Keeping the files without the faces would have
 *       cost nothing on the wire (a face is what triggers a download) but would have left the old
 *       brand one @font-face block away from returning.
 *     - THREE REFERENCES SURVIVE, in files nothing includes: head_v1.0.6.php,
 *       accountLayout_v1.0.1.php, accountLayout_v1.0.2.php. Verified dead — every mention of them
 *       is prose inside their own docblocks, no page includes any of them. Left untouched on
 *       purpose (older versions of an include are not this change's business). If one is ever
 *       resurrected its heading renders Georgia, not Quinstory, so fix the class then.
 *     - WEIGHT CHANGED with the family, owner's call: every Quinstory site was font-normal (31 of
 *       31 — correct for a script face whose natural weight is 400) and is now font-bold. Poppins
 *       at 400 reads visibly thin at the 20-52px these headings use, and the GoTasty design sets
 *       --type-h1/h2 to --fw-bold. Weight is the one thing here that is a judgement, not a fact.
 * 2026-08-19 — GoTasty rebrand, IN-PLACE (values + two new faces; NO token added, renamed or
 *   removed, so all 38 member pages that consume the non-canon --color-* vocabulary keep working
 *   and pick the new palette up for free). Filename kept on purpose: head_v1.0.11's <link> and its
 *   filemtime cache-bust need no edit, which keeps this out of chrome's scope.
 *     - 44 token VALUES swapped MrFlower sage/cream -> GoTasty coral/navy. Anchors:
 *       #68796B sage -> #F06353 coral (primary, brand, links, primary button, sign-in button);
 *       #2C2A22 / #2A2820 / #1C2232 -> #2A2D41 navy (body text, dark surfaces, footer);
 *       #E6E6E6 -> #E5E5EA borders; #767470 -> #727272 muted text; #FFF9F9 / #F9E9E2 -> #FEF3F1
 *       blush; #F6F6F4 -> #F1F1F4 and #FAFAF7 -> #EFEFF2 subtle surfaces; #474747 -> #1E2030.
 *       Derived shades not in the handoff: --color-brand-primary-dark #D94A3A and
 *       --color-brand-primary-light #F58C80 (coral darkened/lightened; the design ships only the
 *       one coral, and these two slots had to hold SOMETHING coherent).
 *     - --header-bg-color #fff3e3 -> #FFFFFF. The design header is plain white. Applied here rather
 *       than deferred to /build-header because the token is theme-owned; the markup is not.
 *     - NEW faces: Poppins (display/headings/buttons, static 400-800) and Nunito Sans (body/UI,
 *       variable 400-800). Latin + latin-ext subsets only — see the note above the blocks for the
 *       285KB of Devanagari/Cyrillic/Vietnamese deliberately left out of the tree.
 *     - Montserrat and Quinstory @font-face blocks were kept at the time of this entry; they were
 *       REMOVED later the same day — see the 2026-08-19 (later) entry at the top.
 *     - NOT TOUCHED, on purpose: --color-bg-otp, --color-pink-soft / -deep / -dark / -vivid and
 *       --color-chip-* . Those are page accents for reset-password, verify-otp, product-detail and
 *       the about/privacy/terms callouts — pages outside this reskin. They still carry MrFlower
 *       pink and WILL look wrong next to the coral once those pages are visited. Revisit each with
 *       its own page reskin.
 *     - ACCESSIBILITY, KNOWN + ACCEPTED (owner decision 2026-08-19: match the design exactly).
 *       Coral #F06353 is design-correct but measures 3.17:1 against white — it FAILS WCAG AA for
 *       normal-size text and passes only AA Large (>=18.66px, or >=14px bold). The sage it replaced
 *       measured 4.63:1 and PASSED, so this is a real regression, not a pre-existing state.
 *         Affected as TEXT: --color-text-link, --color-text-brand, --primary-color where used for
 *         type. Buttons are defensible (labels are >=14px semibold, so AA Large applies).
 *         Measured (WCAG 2.1 relative luminance), for anyone re-checking:
 *           navy #2A2D41 on white .......... 13.55:1  PASS
 *           white on navy .................. 13.55:1  PASS
 *           muted #727272 on white .......... 4.81:1  PASS
 *           coral #F06353 on white .......... 3.17:1  FAIL normal / PASS large
 *           white on coral #F06353 .......... 3.17:1  FAIL normal / PASS large
 *           coral #F06353 on navy ........... 4.27:1  FAIL normal / PASS large
 *         The AA-passing alternative was #B33A2D (5.90:1) for the two TEXT tokens only, keeping
 *         #F06353 for fills. It was rejected in favour of design fidelity. Re-open this if an
 *         accessibility audit or Lighthouse a11y score becomes a release gate.
 *     - Paradigm note: this file predates the /build-theme canonical schema (126 tokens). Only 74
 *       of its 143 names overlap; 69 are non-canon and 52 canonical slots are absent. Adopting canon
 *       is a major bump plus a 38-page rewrite, deliberately NOT done here.
 * 2026-08-17 — v1.0.2 (dead-code removal only — ZERO token/value changes vs v1.0.1; 130 tokens on
 *   both sides, same values, same selector blocks). Deleted 13 @font-face declarations that nothing
 *   applies: MainFont/Heebo (7 weights, .ttf) and HelveticaNeue (6 weights, .otf). Montserrat and
 *   Quinstory are untouched — they are the two faces this portal actually renders.
 *     - A @font-face only downloads when a rule matches an element, so these cost visitors nothing
 *       and the removal changes no byte on the wire. What they cost is 2.8MB of .ttf/.otf that
 *       shipped on every deploy, which is why they are going.
 *     - The only rules naming those families live in css/general_v1.0.0.css (six of them: .datepicker
 *       table tr th, .daterangepicker, .btnPrimaryModal, and a bare `header` element selector). That
 *       stylesheet is NOT LOADED by anything — head_v1.0.11's own changelog says "Not using bootstrap,
 *       custom_v1.0.0.css and general_v1.0.0.css", and the four CSS links a page actually emits are
 *       style.css, main_v1.0.0.css, main_v1.0.0.css (noscript) and this file.
 *     - Verified in the browser, not by reading: across index/blog/track-order/shop/contact-us/sign-up,
 *       zero elements compute to MainFont/HelveticaNeue/Konnect and zero Heebo or HelveticaNeue files
 *       are requested. The four selectors above were then INJECTED into a live page — the datepicker
 *       and modal ones matter because that markup is built by JS and a static scan cannot see it —
 *       and all four resolved to Montserrat, confirming the general_v1.0.0 rules are unreachable
 *       rather than merely unused on the pages sampled.
 *     - The .ttf/.otf files themselves are deleted in the same commit. theme_v1.0.0.css still names
 *       them, and its src URLs are now dangling — inert, because no head has referenced v1.0.0 since
 *       404_v1.0.8 moved off it and every legacy head has zero page callers.
 * 2026-08-13 — ASSET-ONLY note, no edit to any rule below: Quinstory.woff2 re-subset in place,
 *   finishing what the Montserrat entry below started. Same filename, same URL, so the @font-face
 *   block for it is untouched. 20,704 -> 12,036 bytes (-42%).
 *     - This is NOT the same operation as Montserrat, and the difference is the point. Montserrat
 *       had two levers: 969 codepoints to trim (Cyrillic + Greek) and a pile of OpenType features
 *       to drop. Quinstory has NEITHER. Its coverage was already Latin-only (218 codepoints, no
 *       Cyrillic, no Greek, no CJK), and its ONLY features are kern/liga/clig/calt — proven, not
 *       assumed: subsetting with `--layout-features=kern,liga,clig,calt` produces a file BYTE-EQUAL
 *       to subsetting with the features left alone. There was nothing extra in there to remove.
 *     - So the only lever was glyph coverage: 218 -> 104 codepoints, 219 -> 115 glyphs.
 *     - KERNING IS DELIBERATELY KEPT. Dropping GPOS as well would reach 8,588 bytes, another 3.4KB.
 *       Refused: GPOS is 12.4KB of this font's uncompressed weight because it IS the kerning, and
 *       Quinstory is a display face that only ever renders headings — the h1 here is 34-46px, which
 *       is exactly the size where bad letter-fit is visible. Wrong 3.4KB to take.
 *     - THE KEEP-LIST WAS SCANNED, NOT GUESSED, because the failure mode is silent: any codepoint
 *       that renders in Quinstory but is missing from the subset falls back to Georgia mid-heading.
 *       Every codepoint appearing anywhere in the portal's page and lang PHP files was intersected
 *       with the font's cmap; outside printable ASCII that yielded exactly six — À, ÿ, ’, “, ” and •
 *       (glob paths are spelled out here on purpose: a slash-star inside a CSS comment is inert but
 *       makes every comment-balance check and minifier misread the file)
 *       and all six are kept, along with the neighbouring quote range and NBSP as cheap insurance.
 *       Re-run that intersection before trimming further, and note it says nothing about zh-cn:
 *       Quinstory has no CJK, so Chinese headings already fell back before any of this.
 *     - Verified by rendering, not by inspection: the four elements this portal actually draws in
 *       Quinstory (the sign-in h1 and the three footer headings) were screenshotted at 2x before
 *       and after and pixel-compared.
 *   Untouched next door: Quinstory.otf (36KB) is still listed as the second src below. It is never
 *   downloaded — WOFF2 comes first and support is >98% — but it does still ship on every deploy.
 * 2026-08-13 — ASSET-ONLY note, no edit to any rule below: the four Montserrat .woff2 files these
 *   @font-face blocks point at were re-subset in place. Same filenames, same URLs, so nothing in
 *   this file (or in the 17 consumers of it) changed — but the FILES are no longer the stock
 *   Google builds, and that matters to whoever touches them next:
 *     - 61.5-62.5KB each -> 19.0-19.3KB each. 248KB -> 76KB across the four weights.
 *     - Coverage kept: Latin + Latin-Ext + Vietnamese (969 -> 645 codepoints). What was dropped is
 *       Cyrillic and Greek, which this portal cannot produce (locales are en + zh-cn, and Montserrat
 *       never carried CJK — Chinese already falls back to a system face).
 *     - The saving is NOT mostly glyph coverage. Coverage-only subsetting gets 61.5KB -> 38.8KB;
 *       the other half is OpenType layout features. Kept kern/liga/clig/calt, dropped the rest after
 *       checking that nothing in the portal asks for them (no tabular-nums, no small-caps, no
 *       stylistic sets; the only font-feature-settings in the repo is 'liga', on the icon font).
 *     - Verified before install: every codepoint appearing in this portal's own sources AND drawable
 *       by the old font is still drawable by the new one (0 missing), and hhea ascender/descender/
 *       lineGap + unitsPerEm are byte-identical, so nothing reflows.
 *     - RE-SUBSET FROM THE .ttf SIDECARS, never from a .woff2 — Montserrat-<weight>.ttf sits next to
 *       each .woff2, is already in git, and carries the identical 969-codepoint cmap (checked, not
 *       assumed). No separate backup copy is kept precisely because those .ttf ARE the backup;
 *       adding one would have put 262KB of duplicate binaries in git history and on every deploy.
 *       If you ever replace a face with a fresh build, re-run the subset or this portal quietly
 *       goes back to paying 248KB. Recipe:
 *         python3 -m fontTools.subset Montserrat-<w>.ttf \
 *           --unicodes=<latin,latin-ext,vietnamese + this portal's own character census> \
 *           --layout-features=kern,liga,clig,calt --flavor=woff2 \
 *           --output-file=Montserrat-<w>.woff2
 * 2026-08-06 — v1.0.1 (perf, font delivery only — ZERO token/value changes vs v1.0.0).
 *   Lighthouse on the production homepage scored Performance 56 with FCP 8.0s / LCP 13.6s
 *   while TBT was 100ms and CLS was 0 — i.e. not a script or layout problem, a bytes-on-the-
 *   critical-path problem. Fonts were 1.08MB of a 3.33MB page.
 *
 *   (1) font-display: swap added to the 4 Montserrat faces and to Quinstory. They previously
 *       declared NO font-display at all, which means `auto` — browsers treat that as `block`,
 *       so body text stayed INVISIBLE until the webfont arrived. Waiting on a 193KB TTF over
 *       throttled mobile is the direct cause of the 8s first paint. `swap` paints immediately
 *       in the fallback face and re-renders when the webfont lands.
 *       NOT applied to the Material Symbols icon font — that one is font-display: block by a
 *       deliberate, documented decision (main_v1.0.0.css: swap flashes the ligature text, e.g.
 *       the literal word "check_circle", before the glyph resolves).
 *
 *   (2) Montserrat 400/500/600/700 + Quinstory now load WOFF2, with the original TTF/OTF kept
 *       as a second src for any client that cannot take WOFF2 (support is >98%, so in practice
 *       nothing fetches it — browsers pick the first format they understand and never request
 *       the other). Measured on these exact files:
 *         Montserrat-Regular   193.0KB -> 60.1KB   (69% smaller)
 *         Montserrat-Medium    193.1KB -> 60.3KB   (69%)
 *         Montserrat-SemiBold  193.3KB -> 60.5KB   (69%)
 *         Montserrat-Bold      193.5KB -> 61.1KB   (68%)
 *         Quinstory             35.3KB -> 20.2KB   (43%)
 *         TOTAL                808.2KB -> 262.2KB  = 546KB off the critical path
 *       Same outlines, same rendering — WOFF2 is a compression container, not a re-draw.
 *
 *   Heebo / HelveticaNeue / LineAwesome faces are left on TTF/OTF untouched: the homepage does
 *   not request them (a @font-face only downloads when something uses it), so converting them
 *   would be churn with no measured win. Convert if a page that does use them is optimised.
 *
 *   Referenced by head_v1.0.11.php (the homepage head) only — every other head_v* still points
 *   at v1.0.0 by design, per the repo's gradual-rollout rule.
 *
 * 2026-07-08 — Update (non-canon, values-only): BRAND RE-ALIGN to the official
 *   "brand logo-MrFlower-Mar2025.docx" brand book (operator decision — reverses the
 *   2026-06-08 "handoff bundle is authoritative" call; brand book now wins). 4 brand
 *   colours restored/mapped onto brand-bearing slots — functional palette (error/
 *   warning/success, pink product accents, neutrals — not covered by the brand book)
 *   left untouched:
 *     PRIMARY sage #68796B  -> --primary-color, --tertiary-color, --tertiary-text-color,
 *       --fifth-text-color, --btn-primary-bg-color (was #4A5740), --color-brand-primary,
 *       --color-text-brand, --color-text-link. Derived shades: --color-brand-primary-dark
 *       #4E4A28->#4E5B51, --color-brand-primary-light #8C8450->#8B978C, --signin-btn-bg
 *       #4A5740->#4E5B51 + hover #3A4732->#3C4740 (sage-dark). White-on-sage passes AA (~4.65:1).
 *     SECONDARY yellow-green #F7FAE8 -> --secondary-bg-color (was #F6F6F4); also already
 *       at --sixth-color.
 *     TERTIARY grayish-yellow #B0AF9C -> --color-border-warm (was #C7C4A4, nearest slot).
 *     ACCENT strong-green #37B14C -> --color-brand-accent (was #FFC154 gold). NOTE: white
 *       text on this accent is only ~2.3:1 — do NOT place text directly on --color-brand-accent.
 *   Live prod (www.mrflower.com.my) still shows the June handoff design; portal now
 *   diverges from live until the live site is re-synced.
 * 2026-07-03 — Correction: removed a duplicate --btn-primary-bg-color/--btn-primary-text-color
 *   declaration that had been added earlier the same day under a mistaken belief the token was
 *   undefined (a grep search missed the pre-existing `--btn-primary-bg-color :` — space before
 *   the colon — at its real declaration further up this :root block, alongside every other
 *   --btn-* token). Since CSS uses the LAST declaration when a custom property repeats in the
 *   same scope, the duplicate had been silently overriding the real, intentionally-set value
 *   (#4A5740, "unified to match --signin-btn-bg-color" per that declaration's own comment) with
 *   #6B6437 for every consumer (homepageHeader avatar circle + cart badge, products.php,
 *   product-detail.php, verify-link.php, the account-page Save buttons). Reverted; single
 *   source of truth restored.
 * 2026-06-23 — Update (non-canon, values-only): --warning-color #ffe139 -> #E0A800
 *   (vivid yellow -> warm gold/amber). Reads as amber on warning UI (cart "cart updated"
 *   notice border/icon + showMessage warning modal icon) per the design. Token-only;
 *   no page touched, no hardcoded value on the banner.
 * 2026-06-08 — Extend (non-canon, prefix --signin-*): added --signin-btn-bg-color
 *   #4A5740 + --signin-btn-hover-bg-color #3A4732 (Mr Flower "Sign In.html" auth
 *   button — a darker green than the brand --btn-primary-bg-color #6B6437; sign-in
 *   page scope only). Additive; no existing token changed. For /reskin-page sign-in.php.
 * 2026-06-08 — Brand sync to the Mr Flower design handoff bundle (latest link
 *   _6CSNL6Ra... ; operator: bundle is now authoritative, overwrite prior live-synced
 *   values). Values-only, 11 tokens: --primary-color #5E5A34->#6B6437, --tertiary-color
 *   #68796B->#6B6437, --btn-primary-bg-color #68796B->#6B6437 (sage->olive/bronze),
 *   --btn-border-radius 0px->30px (square->pill), --primary-text-color #5E5A34->#2C2A22
 *   (olive->warm-dark body text), --default-secondary-bg-color #fff->#FAFAF7 (warm page bg),
 *   --secondary-bg-color #f7f7f7->#F6F6F4, --fourth-text-color #545454->#767470 (muted),
 *   --error-color #fb403a->#FD397A, --success-color #2CAA0D->#00B900, --input-bg-color
 *   #FFFFFF->#F3F3F3. Text-size scale kept (member uses 17px; bundle 14px would regress).
 *   Footer #2A2820 already synced (2026-06-08 prior entry). Portal-wide.
 * 2026-06-08 — Follow-exactly extension (operator: match the bundle's :root precisely).
 *   Text scale: xs 12->11, sm 15->13, md 17->15, lg 24->18, xl 37->24. Font-weights:
 *   medium 400->500, thick 500->600. Buttons: secondary-bg #FFF->#F6F6F4, secondary-text
 *   #fff->#2C2A22, disabled-bg #d3d3d3->#CDCDCD, width-short 100->120px, font-size 17->14px,
 *   button-border 2px #C1BFA9 -> 1px #CDCDCD. Text: tertiary-text #000->#6B6437, fifth-text
 *   #89855D->#6B6437. Borders: --default-border #ddd->#E6E6E6, --primary-border-color
 *   #DEDEDE->#E6E6E6. Listing: header-text-size 17->13px, header-child-color #000->#767470.
 *   NOT in bundle (left as-is, flagged): --input-label/text/placeholder-size (17px),
 *   --footer-text-size (15px), --header-bg/text-color, --warning-color, --secondary-color.
 * 2026-06-08 — Values-only: --footer-bg-color #68796B (sage) -> #2A2820 (dark warm
 *   charcoal). Matches the Mr Flower Homepage.html design (Claude Design handoff
 *   bundle: --color-bg-dark, used for footer + announcement bar). Footer bg now dark
 *   portal-wide; --footer-text-color stays #FFFFFF. Upstream of /build-footer
 *   homepageFooter_v1.0.3.
 * 2026-06-04 — Values-only: --btn-primary-text-color #5E5A34 -> #ffffff. The sage
 *   primary button (--btn-primary-bg-color #68796B) needs white text to match live
 *   (white-on-sage) and pass WCAG AA (olive-on-sage was ~1.4:1; white-on-sage ~4.65:1).
 *   Surfaced by wf-ai-review-runner color-contrast on member/sign-in.php. Portal-wide.
 * 2026-06-04 — Brand refresh to production www.mrflower.com.my (source: live
 *   :root tokens via Playwright). Values-only sync of 16 tokens: red (#E21E25)
 *   -> sage/olive florist palette (primary-text + btn-primary -> #5E5A34 /
 *   #68796B), square buttons (btn-border-radius 0px), sage footer (#68796B),
 *   fixed text sizes (clamp() -> px), input label/text/placeholder 15 -> 17px,
 *   input-border #DEDEDE -> #aaa. No tokens added/removed; filename kept.
 */
/* ── GoTasty faces (2026-08-19). Poppins = display/headings + buttons, Nunito Sans = body/UI.
 * Latin + latin-ext subsets ONLY. The handoff also shipped Devanagari (5 x 39KB), Cyrillic
 * (2 x ~37KB) and Vietnamese (16KB) subsets — 285KB of glyphs this portal (en + zh-cn) can
 * never render, so they are not in the tree. Poppins is static-per-weight; Nunito Sans is a
 * variable font, so ONE file covers 400-800 per subset.
 * Montserrat + Quinstory are GONE (2026-08-19): every reference across the portal was converted
 * to font-display / font-sans, so the faces had nothing left to resolve and both they and
 * their files were deleted. These two families are the whole type system now. */
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-400.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-ext-400.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-500.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-ext-500.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-600.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-ext-600.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-700.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-ext-700.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-800.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url(fonts/Poppins/poppins-latin-ext-800.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Nunito Sans';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url(fonts/NunitoSans/nunitosans-latin.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Nunito Sans';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url(fonts/NunitoSans/nunitosans-latin-ext.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}



:root{
    /* 2026-06-14: portal-wide font scale. Edit --font-scale to resize ALL text.
       Every --*-text-size + --fs-* below is calc(basepx * --font-scale). */
    --font-scale: 1;
    --fs-10: calc(10px * var(--font-scale));
    --fs-12: calc(12px * var(--font-scale));
    --fs-16: calc(16px * var(--font-scale));
    --fs-17: calc(17px * var(--font-scale));
    --fs-19: calc(19px * var(--font-scale));
    --fs-20: calc(20px * var(--font-scale));
    --fs-22: calc(22px * var(--font-scale));
    --fs-26: calc(26px * var(--font-scale));
    --fs-28: calc(28px * var(--font-scale));
    --fs-30: calc(30px * var(--font-scale));
    --fs-32: calc(32px * var(--font-scale));
    --fs-34: calc(34px * var(--font-scale));
    --fs-36: calc(36px * var(--font-scale));
    --fs-38: calc(38px * var(--font-scale));
    --fs-40: calc(40px * var(--font-scale));
    --fs-42: calc(42px * var(--font-scale));
    --fs-44: calc(44px * var(--font-scale));
    --fs-46: calc(46px * var(--font-scale));
    --fs-48: calc(48px * var(--font-scale));
    --fs-52: calc(52px * var(--font-scale));

    /* NEW STANDARD ROOT CSS */
    /*theme-color*/
    --primary-color : #F06353;
    --secondary-color: #2A2D41;
    --tertiary-color: #F06353;
    --fourth-color: #2A2D41;
    --fifth-color: #F1F1F4; 
    --sixth-color: #FEF3F1;
    --error-color: #DC3B2E;
    --warning-color: #F2A33C;
    --success-color: #2E9E5B;
    --hyperlink-text-color: #0000EE;

 /*webpage*/
    --default-border: 1px solid #E5E5EA;
    --default-bg-color: #fff;
    --default-primary-bg-color: #000;
    --default-secondary-bg-color: #EFEFF2;
    --default-primary-text-color: #000;
    --default-secondary-text-color: #fff;
    --primary-border-color: #E5E5EA;
    --secondary-border-color: #EDEDF1;   /* CANON slot, was missing from this file. Hairline
                                            dividers (summary panel sections, table cells).
                                            Canon default #F1F2F4; design wins at #EDEDF1. */
    --primary-bg-color : #fff;
    --secondary-bg-color: #FEF3F1;
    --primary-text-color:#2A2D41;
    --secondary-text-color : #fff;
    --tertiary-text-color : #43434A;
    --fourth-text-color : #727272;
    --fifth-text-color : #727272;
    --onhover-text-color: #000;
    --default-border-radius: 10px;
    --xl-text-size: calc(24px * var(--font-scale));
    --lg-text-size: calc(18px * var(--font-scale));
    --md-text-size: calc(15px * var(--font-scale));
    --sm-text-size: calc(13px * var(--font-scale));
    --xs-text-size: calc(11px * var(--font-scale));
    --header-height: auto;
    --border-radius-xs: 5px;
    --border-radius-md: 10px;
    --border-radius-lg: 15px;
    --border-radius-full: 9999px;   /* CANON slot, was missing from this file. Pills / badges /
                                       fully-rounded buttons. Exactly the design's pill radius, so
                                       --btn-border-radius (30px) is deliberately NOT retuned. */
    --card-border-radius: 16px;     /* CANON slot, was missing. Design's card/panel radius.
                                       Canon default is var(--border-radius-md); design wins. */
    --radius-panel: 14px;
    --radius-menu-item: 9px;
    --radius-option-row: 12px;      /* NEW. Selectable option rows (shipping-method,
                                       payment-method). No canon step exists between 10px and
                                       15px, and page-reskin's step-9b gate forbids a raw 12px
                                       literal in markup, so this has to be a real token. */
    --js-header-height: 80px;

/* font-weight */
    --default-font-weight-thin: 300;
    --default-font-weight-medium: 500;
    --default-font-weight-thick: 600;
    --default-font-weight-bold: 700;
    --default-font-weight-max: 900;

/*button*/
    --btn-primary-bg-color :  #F06353;   /* 2026-08-19 GoTasty coral. History (MrFlower): #68796B sage from 2026-07-08, #4A5740 before that, #6B6437 olive before that. CONTRAST NOT RE-VERIFIED — the sage note claimed white text at ~4.65:1, but coral #F06353 with #ffffff is ~3.1:1, which FAILS WCAG AA for normal text and passes only for large/bold. The design itself uses white-on-coral buttons, so this matches the reference; flag it if AA on small button text is required. */
    --btn-secondary-bg-color : #F1F1F4;
    --btn-tertiary-bg-color : #fff;
    --btn-disabled-bg-color : #CDCDCD;
    --btn-onHover-primary-bg-color : '';
    --btn-onHover-secondary-bg-color : '';
    --btn-onHover-tertiary-bg-color : '';
    --btn-primary-text-color: #ffffff;
    --btn-secondary-text-color: #2A2D41;
    --btn-tertiary-text-color: #000;
    --btn-disabled-text-color: #9d9d9d;
    --btn-onHover-primary-text-color : '';
    --btn-onHover-secondary-text-color : '';
    --btn-onHover-tertiary-text-color : '';
    --btn-width-long: 200px;
    --btn-width-short: 120px;
    --btn-border-radius: 30px;
    --button-border: 1px solid #CDCDCD;
    --btn-font-size : 14px;

/*input*/
    --input-label-size: 16px;
    --input-text-size: calc(16px * var(--font-scale));
    --input-border-radius: 5px;
    --input-border : 1px solid #aaa;
    --input-bg-color :#F3F3F3;
    --input-width-long: '';
    --input-width-short: '';
    --input-placeholder-size: 16px;
    --input-placeholder-color: #A6A6AE;
    --input-disabled-bg-color: #d6d6d6;
    --input-onfocus-border-color: '';

/*header*/
    --header-bg-color: #FFFFFF;
    --header-text-size: calc(17px * var(--font-scale));
    --header-text-color: #000;
    --header-onHover-color: '';

/*footer*/
    --footer-bg-color: #2A2D41;
    --footer-text-size: calc(15px * var(--font-scale));
    --footer-text-color: #FFFFFF;
    --footer-border-color: rgba(255,255,255,0.15);
    --footer-onHover-color: '';

/*listing*/
    --listing-header-color: #F1F1F4;
    --listing-row-primary-color: #f8f8f8;
    --listing-row-secondary-color: #fff;
    --listing-header-child-color: #727272;
    --listing-row-child-primary-color: #FEF3F1;
    --listing-row-child-secondary-color: #FEF3F1;
    --listing-header-text-size: calc(13px * var(--font-scale));
    --listing-row-text-size: calc(17px * var(--font-scale));
    --listing-header-child-text-size: calc(17px * var(--font-scale));
    --listing-row-child-text-size: calc(17px * var(--font-scale));

    /* ── Non-canonical extension — prefix: --signin-* (sign-in page scope) ──
       Added 2026-06-08 (see changelog). The Mr Flower "Sign In.html" design
       (Claude Design bundle) hardcodes a DARKER auth-button green than the
       brand button (--btn-primary-bg-color #6B6437). Scoped to the sign-in
       page so the portal-wide button is unaffected. Consumed by
       member/sign-in.php via bg-[color:var(--signin-btn-bg-color)]. */
    --signin-btn-bg-color: #F06353;
    --signin-btn-hover-bg-color: #D94A3A;

    /* ── Mr Flower design-system primitives (--color-* mirror) ──────────────────
       Added 2026-06-10 via /build-theme (Extend path). Source: the MrFlower design
       system colors_and_type.css (Claude Design bundle). ADDITIVE ONLY — no existing
       token above was changed; the legacy semantic aliases already equal these values.
       Non-canonical extension under the explicit --color-* prefix (the design system's
       own namespace), NOT the locked 126-token canonical schema. Consumed by pages via
       bg-[color:var(--color-bg-warm)] etc. Lets about-us / terms / privacy / the modal
       re-point their inlined one-off hex to real tokens. */
    /* Brand */
    --color-brand-primary:       #F06353;
    --color-brand-primary-dark:  #D94A3A;
    --color-brand-primary-light: #F58C80;
    --color-brand-primary-hover: #E14A39;  /* 2026-08-20: the design's --brand-hover, which it
       defines as --coral-600 (#E14A39) — the same rung as --color-text-link, but a BUTTON
       BACKGROUND role, so it gets its own name rather than a text token doing double duty.
       Measured on the Blog handoff's CTA button: .scp4:hover sets background #E14A39. */
    --color-brand-primary-deep:  #BE3A2B;  /* 2026-08-20: the design's own --coral-700, declared in the Blog Article handoff's :root. NOT derived. It is the text colour the design puts on a --color-brand-blush (#FEF3F1) ground - the pale-pill case, where plain coral #F06353 is too light to read and --color-brand-primary-dark (#D94A3A) is a different hue. First used by blog-detail.php's category pill, tag-pill hover and Sources link hover. */
    --color-brand-accent:        #F06353;
    --color-brand-blush:         #FEF3F1;  /* design token — subtle accents (subcategory border-left, etc.) */
    --color-brand-blush-deep:    #F8C3B9;  /* 2026-08-20: the design's own --coral-200, declared
       in the Blog handoff's :root — so the 2026-08-19 value #FDE0DB (DERIVED from #FEF3F1,
       itself replacing MrFlower #FFDDE0) is no longer a guess and is superseded. Used on the
       product card image frame, the Promise divider rule, the featured-carousel arrow hover
       border, and now the blog CTA band's top rule. Distinct from --color-brand-blush. */
    /* Backgrounds */
    --color-bg-white:            #FFFFFF;
    --color-bg-warm:             #EFEFF2;
    --color-bg-light:            #F1F1F4;
    --color-bg-subtle:           #F8F8FA;
    --color-bg-pink-subtle:      #FEF7F5;
    --color-bg-cream-subtle:     #F1F1F4;
    --color-bg-dark:             #2A2D41;
    --color-bg-dark-mid:         #1E2030;
    /* Borders */
    --color-border-default:      #E5E5EA;
    --color-border-warm:         #D2D2D9;
    --color-border-product:      #E5E5EA;
    /* Text */
    --color-text-primary:        #2A2D41;
    --color-text-secondary:      #FFFFFF;
    --color-text-neutral:        #595960;  /* 2026-08-20: the design's own --neutral-600,
       declared in the Blog handoff's :root. NOT derived. Sits between --color-text-primary
       (#2A2D41) and --color-text-muted (#727272): the design uses it for the uppercase
       category label on a --color-bg-light (#F1F1F4) pill, where #727272 loses contrast
       against the grey and #2A2D41 reads as a heading. First used by _blog-card.php. */
    --color-text-muted:          #727272;
    --color-text-faint:          #A6A6AE;
    --color-text-label:          #595960;
    --color-text-brand:          #F06353;
    --color-text-link:           #E14A39;  /* 2026-08-20: was #F06353. The design system
       declares --text-link as --coral-600 (#E14A39), not --coral-500 — measured in the Blog
       handoff's :root and on its card "Read" link. #F06353 on white is ~3.1:1, which fails AA
       for the 14px link text it is used on; #E14A39 is ~4.0:1. Two consumers, both underlined
       body links, both improved: .blog-body a (input.css) and #legalDoc .legal-body a
       (terms-and-conditions.php). Owner decision 2026-08-20 (design-wins). */
    --color-text-error:          #DC3B2E;
    --color-text-success:        #2E9E5B;
    --color-text-disabled:       #9D9D9D;
    /* Typography scale (design default; member theme had sm/md but not default) */
    --default-text-size: calc(14px * var(--font-scale));

    /* Status-badge pairs — centralizes colors that were previously hardcoded hex, repeated
       across my-orders.php (order-status pills) and addresses.php ("not deliverable" badge).
       Added 2026-07-03 (design-consistency audit). Values match what was already live —
       this is a rename/centralize, not a re-color. */
    --badge-warning-bg:     #FEF3C7;
    --badge-warning-text:   #B45309;
    --badge-warning-border: #FDE68A;
    --badge-info-bg:        #E8F0FE;
    --badge-info-text:      #1A56DB;
    --badge-purple-bg:      #E0E7FF;
    --badge-purple-text:    #3730A3;
    --badge-success-bg:     #D4EDDA;
    --badge-success-text:   #155724;
    --badge-danger-bg:      #F8D7DA;
    --badge-danger-text:    #721C24;

    /* Design-token audit 2026-07-06 — centralize colors that were hardcoded (repeated)
       across member pages. Values match what was already live (rename/centralize, not re-color).
       - OTP verify box bg: reset-password.php + verify-otp.php (7 hits)
       - Pink accents: product-detail sale pills + about-us/privacy/terms callouts
       - Grey chips: product-detail size/variant selector chips */
    --color-bg-otp:         #F0EDD0;
    --color-pink-soft:      #F2C4C8;
    --color-pink-soft-deep: #ECB1B7;
    --color-pink-dark:      #6B2737;
    --color-pink-vivid:     #E74C6F;
    --color-chip-bg:        #F0F0F0;
    --color-chip-bg-active: #E0E0E0;
    --color-chip-border:    #C8C8C8;
    --color-chip-text:      #555555;

    /* Surfaces on dark, overlays, elevation and focus — added 2026-08-20 with the GoTasty
       chrome rebuild. Every one of these replaced a literal that was sitting in page markup
       (a raw rgba() in a Tailwind arbitrary value, or a bg-white/NN opacity utility), which
       is exactly what the no-hardcoded-values-at-page-level rule forbids. Values are the
       design system's own; the mapping to its token names is in the changelog at the top. */
    --surface-on-dark:        rgba(255,255,255,0.10);
    --surface-on-dark-hover:  rgba(255,255,255,0.20);
    --overlay-bg-color:       rgba(42,45,65,0.50);
    --overlay-strong-bg-color: rgba(42,45,65,0.70);
    --focus-ring-color:       rgba(240,99,83,0.13);
    --shadow-sm:              0 1px 3px rgba(42,45,65,0.07);
    /* 2026-08-20 — four elevations read straight off the GoTasty Blog handoff's own CSS, not
       were carrying a raw rgba() literal before this entry. The two hover values differ by 2px of
       blur and offset because the design genuinely uses a slightly larger lift on the wide hero
       panel (.scp2) than on a grid card (.scp3) — kept separate rather than averaged. */
    --shadow-card:            0 1px 3px rgba(42,45,65,0.06);    /* card + panel at rest */
    --shadow-card-hover:      0 14px 34px rgba(42,45,65,0.13);  /* grid card hover (.scp3) */
    --shadow-panel-hover:     0 16px 40px rgba(42,45,65,0.13);  /* wide hero panel hover (.scp2) */
    --shadow-brand:           0 8px 24px rgba(240,99,83,0.34);  /* coral button hover (.scp4) */
    --shadow-dropdown:        0 12px 30px rgba(42,45,65,0.16);
    --shadow-drawer:          -8px 0 30px rgba(42,45,65,0.22);

    /* NON-CANONICAL EXTENSION — 2026-08-20, GoTasty Home body reskin. Roles the Home design draws
       that NO existing token covers, so page markup had nothing to point at. Named under this
       file's established --color-* convention (the same one --color-pink-vivid / --color-chip-bg
       use), NOT a new prefix. Each mirrors a value the design declares:
         --color-star-gold    <- the testimonial card's 5-star row (design #F5A623). The stars were
                                 coral (--color-brand-accent) before, which is the brand colour,
                                 not a rating colour; the design draws them gold.
         --color-whatsapp-bg  <- the contact panel's WhatsApp icon tile ground (design #E7F9EE).
         --color-whatsapp     <- WhatsApp brand green (design #25D366). A THIRD-PARTY BRAND colour,
                                 deliberately not folded into --success-color (#2E9E5B): they are
                                 near-neighbours but mean different things, and reusing the success
                                 token here would make a later success-colour change silently
                                 repaint the WhatsApp mark. */
    --color-star-gold:        #F5A623;
    --color-whatsapp-bg:      #E7F9EE;
    --color-whatsapp:         #25D366;
    /* 2026-08-21: two more third-party brand marks, same rule as --color-whatsapp — declared once
       here so no page carries the literal; never restyle them to brand tokens. */
    --color-facebook:         #1877F2;
    --color-instagram-gradient: linear-gradient(45deg, #F9CE34, #EE2A7B, #6228D7);

    /* Elevation + on-dark values the Home body needs. ADDITIVE ONLY — nothing already on a page
       changes. Each replaced a raw rgba() sitting inside a Tailwind arbitrary value in index.php,
       which LAW 1 forbids at page level.
         --shadow-lift             <- the "what we sell" card's lift on hover (translateY -4px)
         --border-on-dark          <- hairline on the dark services cards. NOT folded into
                                      --surface-on-dark (rgba(255,255,255,0.10)): that is a SURFACE
                                      fill and this is a BORDER, they differ in alpha, and the
                                      design names them separately.
         --text-on-dark-muted /    <- the two on-dark values the services band needs as TOKENS
         --surface-on-dark-subtle     rather than Tailwind's white/NN opacity utilities. Not
                                      cosmetic: `text-white/70` computes to oklab(...) in current
                                      Chromium while the design's own rgba(255,255,255,.7) stays
                                      rgba, so a design-fidelity comparison reported them as
                                      different COLOURS when they render identically.
       WHAT THIS ENTRY NO LONGER DECLARES, and why. The Home pass also added --shadow-card,
       --shadow-card-hover and --shadow-brand. All three arrived FIRST from the GoTasty Blog pass
       (see the changelog entries above) while this work sat unmerged, so the Blog values stand and
       this entry reuses them rather than re-declaring. Two of them differ between the two designs'
       readings — card-hover 0 14px 34px here vs 0 6px 18px in the Home export, brand 0 8px 24px vs
       0 6px 20px — and the committed Blog value was kept in both cases. If the Home export is the
       authority for those two, change them HERE, in one place; do not add a second name. */
    --shadow-lift:            0 14px 36px rgba(42,45,65,0.13);
    --border-on-dark:         rgba(255,255,255,0.14);
    --text-on-dark-muted:     rgba(255,255,255,0.70);
    --surface-on-dark-subtle: rgba(255,255,255,0.05);

    /* 2026-08-21 standardisation pass — shared literals promoted to tokens. See changelog.
       --hero-scrim-gradient        <- the photo-hero ink scrim every public hero repeats
                                       (products, sign-in, sign-up, reset-password). One token,
                                       one place to retint.
       --hero-scrim-gradient-strong <- the heavier variant (contact-us, welcome, careers).
       --hero-text-shadow           <- white hero headline legibility shadow (sign-in/up, welcome).
       --shadow-modal               <- the ONE modal/dialog elevation. Replaces four near-identical
                                       one-offs (28,30,44/.3 · 0,0,0/.22 · 0,0,0/.25 · 42,45,65/.12).
       --shadow-panel               <- soft resting shadow of the big auth/OTP white cards.
       --toast-warning-*            <- toast palette out of head_v* CSS; values unchanged.
       --toast-error-border         <- was #d62a64 (Metronic pink relic); now darker brand red.
       --loader-size                <- full-screen loader glyph size (head_v* spinner). */
    --hero-scrim-gradient:        linear-gradient(90deg, rgba(16,18,28,.72) 0%, rgba(16,18,28,.45) 52%, rgba(16,18,28,.55) 100%);
    --hero-scrim-gradient-strong: linear-gradient(90deg, rgba(16,18,28,.86) 0%, rgba(16,18,28,.62) 52%, rgba(16,18,28,.72) 100%);
    --hero-text-shadow:           0 2px 14px rgba(0,0,0,.40);
    --shadow-modal:               0 24px 60px rgba(28,30,44,.30);
    --shadow-panel:               0 4px 26px rgba(42,45,65,.07);
    --toast-warning-bg:           #B7791F;
    --toast-warning-border:       #9C6717;
    --toast-error-border:         #C33427;
    --loader-size:                70px;
}

