/* =========================================================================
   LONDON FASHION DAY - DESIGN TOKENS
   The canonical source for every NEW LFD component. Legacy Manon and legacy LFD
   components are untouched and keep working exactly as they do today.

   THIS FILE PAINTS NOTHING. It declares custom properties and nothing else: no
   element selector, no !important, no rule that produces a pixel. That is the
   property that makes this commit a foundation rather than a redesign, and
   tests/test_design_system.py asserts it on every run.

   WHY THE NAMES LOOK LIKE THIS
   The --lfd-* namespace is ALREADY IN USE. Four canonical stylesheets declare
   their own sets, component-scoped, with values that disagree:

     body.lfd-custom-header-enabled   --lfd-black #0c0c0c  --lfd-line rgba(12,12,12,.15)
     .lfd-news-entry                  --lfd-black #050505  --lfd-line rgba(0,0,0,.14)
     .lfd-single-entry                --lfd-black #050505  --lfd-line rgba(0,0,0,.14)
     body .lfd-news-archive           --lfd-text  #070707  --lfd-line rgba(7,7,7,.13)

   None of them is on :root, so :root is free - but a bare --lfd-black here would
   be one inheritance hop from silently changing a component if a scope ever moved.
   So every token in this file carries a CATEGORY SEGMENT (--lfd-color-*,
   --lfd-space-*, --lfd-size-*, ...) and none can collide with a legacy name, all
   of which are single-segment. The test enforces that too.

   Four properties are deliberately ABSENT: --lfd-panel-top, --lfd-panel-width,
   --lfd-panel-left and --lfd-panel-stop-top. news-archive.css reads them with CSS
   fallbacks and news-archive.js sets them at runtime. Declaring them here would
   replace the fallback for the frames before the script runs.

   PROVENANCE
   Values come from the canonical design as measured, not from preference:
   audit/11_canonical_design_inventory.md, reproducible with
   `python3 tools/extract_canonical_tokens.py`. Where the canonical files and the
   Brand Book disagree, the canonical files win and the disagreement is recorded
   as an owner question (C1, T1, T2, G1) rather than silently resolved.
   ========================================================================= */

:root {

  /* ---------------------------------------------------------------------
     COLOUR
     16 distinct hex values across 132 occurrences in the canonical CSS. This
     is that set, deduplicated: the nine one-off drift values (#222, #333,
     #fafafa, #f5f5f5, #f3f3f3, #f7f7f7, #080808 ...) are near-duplicates of a
     token that already exists and are not reproduced as tokens.

     C1 - DECIDED, APPROVED. #000000 is the canonical ink for new LFD
     components. #0c0c0c stays available as --lfd-color-ink-legacy, a
     documented reference colour for compatibility only; it is deliberately
     absent from theme.json so the editor cannot offer it, and no new component
     may use it. Existing legacy colours are NOT mass-replaced.
     --------------------------------------------------------------------- */
  --lfd-color-ink: #000;          /* canonical ink for new components     */
  --lfd-color-ink-deep: #050505;     /* 26 uses - panels, dark sections      */
  --lfd-color-ink-soft: #111;     /* 8 uses - Manon's body copy colour    */
  --lfd-color-ink-legacy: #0c0c0c;   /* compatibility reference only - C1    */

  --lfd-color-paper: #fff;        /* 50 uses                              */
  --lfd-color-paper-warm: #fbfaf8;   /* 2 uses - warm panel ground           */
  --lfd-color-mist: #f6f6f6;         /* 4 uses - soft section ground         */

  --lfd-color-gold: #b39258;         /* the signature accent. ONE use in     */
                                     /* 156 KB of canonical CSS - far rarer  */
                                     /* than the Brand Book implies.         */
  --lfd-color-focus: #8a671f;        /* focus ring; darker gold, AA on paper */

  /* The season accent. A season term carries an accent colour; the season
     theme writes --lfd-season-accent and every accent use reads it through
     this one indirection, so a season with no accent still renders finished. */
  --lfd-color-accent: var(--lfd-season-accent, var(--lfd-color-gold));
  --lfd-color-accent-ink: var(--lfd-season-ink, var(--lfd-color-ink-deep));

  /* The accent AS TEXT ON PAPER, which is a different job from the accent.
     --lfd-color-accent is chosen for a poster, a rule, a focus ring; the gold
     default is 2.9292:1 on white and cannot carry 9px type. This is the same
     colour at reading weight: the darker gold already in this file, 5.1973:1
     on paper and 4.8092:1 on --lfd-color-mist.
     Nothing that fills or outlines changes - only accent text on paper.

     --lfd-season-accent-text IS NOW WRITTEN, and this comment previously said
     the opposite - correctly, at the time: nothing in the repository set it,
     the only wired chain was --lfd-season-accent, and a season that wanted
     darker accent text had to set this by hand, which no season did.

     It is DERIVED now, not edited. lfd_accent_custom_properties() emits it
     beside the accent from the single colour the editor chose, keeping the hue
     and darkening until 4.5:1 on paper. A season accent of #ffff00 is 1.0738:1
     and becomes #7a7a00 at 4.5540:1; the gold default is 2.9292:1 and becomes
     #8c7245. The fallback below still holds for markup that never calls it. */
  --lfd-color-accent-text: var(--lfd-season-accent-text, var(--lfd-color-focus));

  /* THE SAME JOB ON THE OTHER GROUND. A colour that carries text on paper cannot carry it on
     ink and the reverse is equally true, so there are two derived variants rather than one
     that is wrong half the time. The card poster's title sits on a dark scrim over a
     photograph; the season chip's mark sits on --lfd-color-ink. Both were reading the raw
     --lfd-color-accent, which is 2.9292:1 on paper by default and whatever an editor typed
     otherwise.

     BOTH ARE DERIVED, NOT EDITED. lfd_accent_custom_properties() in the design-system layer
     writes --lfd-season-accent-text and --lfd-season-accent-on-ink from the one colour the
     editor chose, keeping its hue and moving away from the backdrop until it clears 4.5:1.
     A second editable field was the alternative and is worse: two colours that can disagree,
     one of them checked.

     The fallback is the gold itself, which is 6.9580:1 on --lfd-color-ink-deep - so markup
     that never calls the deriver still renders readable accent text on ink. */
  --lfd-color-accent-on-ink: var(--lfd-season-accent-on-ink, var(--lfd-color-gold));

  /* ---------------------------------------------------------------------
     ALPHA SCALE
     75 distinct rgb/rgba values, written both spaced and unspaced, with at
     least five different "hairline" opacities (.035 .06 .08 .12 .14). There
     was no scale. This is one.
     --------------------------------------------------------------------- */
  --lfd-alpha-ghost: 0.035;
  --lfd-alpha-faint: 0.06;
  --lfd-alpha-soft: 0.08;
  --lfd-alpha-line: 0.12;
  --lfd-alpha-rule: 0.14;
  /* 0.48 was the measured legacy value and it is NOT usable for text: black at
     0.48 on paper is #858585, 3.6900:1, below the 4.5:1 that WCAG 2.2 AA asks
     of small type. 0.55 is #737373, 4.7417:1 - the nearest value on this scale
     that actually passes, and visually indistinguishable at the 9-10px
     micro-label sizes that use it. The alpha scale is what components read, so
     raising it here is what stops the next quiet label failing, and three of
     them have since been moved onto it.

     THE NUMBERS ABOVE WERE WRONG WHEN THIS COMMENT WAS WRITTEN: it claimed
     3.35:1 for 0.48 and 4.76:1 for 0.55. Both were close enough to be believed
     and neither was computed. Recomputed from the sRGB relative-luminance
     formula, and on the other two grounds this scale lands on as well:
     0.55 is 4.7326:1 on --lfd-color-paper-warm and 4.6496:1 on
     --lfd-color-mist, so it passes on every surface, not just on paper. */
  --lfd-alpha-muted: 0.55;
  --lfd-alpha-body: 0.62;
  --lfd-alpha-strong: 0.72;

  /* Resolved surfaces, so a component never writes a bare rgba() again. */
  --lfd-color-line-ghost: rgb(0 0 0 / var(--lfd-alpha-ghost));
  --lfd-color-line-faint: rgb(0 0 0 / var(--lfd-alpha-faint));
  --lfd-color-line-soft: rgb(0 0 0 / var(--lfd-alpha-soft));
  --lfd-color-line: rgb(0 0 0 / var(--lfd-alpha-line));
  --lfd-color-rule: rgb(0 0 0 / var(--lfd-alpha-rule));
  --lfd-color-text-muted: rgb(0 0 0 / var(--lfd-alpha-body));
  --lfd-color-text-quiet: rgb(0 0 0 / var(--lfd-alpha-muted));

  /* The same scale inverted, for dark sections - the home hero, the board,
     the prev/next capsule. */
  --lfd-color-line-on-dark: rgb(255 255 255 / var(--lfd-alpha-soft));
  --lfd-color-rule-on-dark: rgb(255 255 255 / 0.22);
  --lfd-color-text-muted-on-dark: rgb(255 255 255 / 0.68);

  /* Status. Not present in the canonical CSS; taken from the Brand Book,
     which is the only source for them. Flagged so nobody mistakes them for
     measured values. */
  --lfd-color-error: #b42318;
  --lfd-color-success: #157347;

  /* ---------------------------------------------------------------------
     TYPOGRAPHY - FAMILIES
     Only two families are declared in the canonical CSS. Open Sans is NEVER
     declared there: body text inherits from Manon, which style_dynamic.css
     sets from the site's Theme Options. That is a real dependency, not an
     oversight.

     T2 - DECIDED, APPROVED. Open Sans is the body face for NEW LFD-owned
     components and redesigned LFD page experiences. Legacy Manon body
     typography is NOT changed globally: migration is component- and
     page-scoped, so the new edition gets a defined typography contract
     without repainting existing Elementor and Manon content. This layer still
     applies the face only through opt-in classes - there is no global rule.
     --------------------------------------------------------------------- */
  --lfd-font-display: "Oswald", "Arial Narrow", Arial, sans-serif;
  --lfd-font-editorial: Georgia, "Times New Roman", Times, serif;
  --lfd-font-body: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --lfd-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* ---------------------------------------------------------------------
     TYPOGRAPHY - SIZE
     280 font-size declarations, 98 distinct values. The mass of the system
     sits between 8px and 15px: the uppercase letter-spaced eyebrows, season
     markers, dates and section labels that carry the design. Display type is
     separately fluid - clamp() is used 47 times with 46 distinct curves.

     Two scales, because they are two different things.
     --------------------------------------------------------------------- */

  /* Label scale - fixed px, because these are optical sizes that must not
     grow with the viewport. This IS the working set, in its measured order
     of use: 11px (26), 10px (24), 14px (22), 15px (18), 12px (16), 13px (16). */
  --lfd-size-label-3xs: 0.5625rem; /*  9px - the smallest legible tracked label */
  --lfd-size-label-2xs: 0.625rem;  /* 10px */
  --lfd-size-label-xs: 0.6875rem;  /* 11px - most used size in the design */
  --lfd-size-label-sm: 0.75rem;    /* 12px */
  --lfd-size-label-md: 0.8125rem;  /* 13px */
  --lfd-size-label-lg: 0.875rem;   /* 14px */

  /* Body scale. 15px is the canonical preview body; 17px is what Manon's
     Theme Options set for <p> on the live site. Both are kept because both
     are real. */
  --lfd-size-body-sm: 0.875rem;    /* 14px - captions, metadata paragraphs */
  --lfd-size-body: 0.9375rem;      /* 15px */
  --lfd-size-body-lg: 1.0625rem;   /* 17px - Manon's live <p> size         */
  --lfd-size-lead: clamp(1.0625rem, 0.95rem + 0.55vw, 1.375rem); /* 17-22px */

  /* Display scale - 46 bespoke clamp() curves systematised into six steps.
     Each is a straight line between a phone size and a desktop size; the
     endpoints are taken from the curves that actually appear in the
     canonical CSS (72/185, 62/135, 42/66 ...). */
  --lfd-size-display-3xl: clamp(4.5rem, 2.2rem + 11vw, 11.5625rem);  /*  72-185px */
  --lfd-size-display-2xl: clamp(3.875rem, 2rem + 8.4vw, 8.4375rem);  /*  62-135px */
  --lfd-size-display-xl: clamp(3rem, 1.9rem + 5.2vw, 5.625rem);      /*  48-90px  */
  --lfd-size-display-lg: clamp(2.625rem, 1.9rem + 3.4vw, 4.125rem);  /*  42-66px  */
  --lfd-size-display-md: clamp(2rem, 1.55rem + 2.1vw, 2.875rem);     /*  32-46px  */
  --lfd-size-display-sm: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);      /*  22-32px  */

  /* ---------------------------------------------------------------------
     TYPOGRAPHY - WEIGHT
     T1 - DECIDED, APPROVED. 700 is the maximum real Oswald weight and the
     maximum this scale offers. Synthetic 850 and 950 are not used in new
     components. Existing legacy occurrences may remain until their component
     is migrated. If a future design genuinely needs heavier, that is a FONT
     decision - a face that ships the weight - not synthetic emboldening.
     --------------------------------------------------------------------- */
  --lfd-weight-regular: 400;
  --lfd-weight-medium: 500;
  --lfd-weight-semibold: 600;
  --lfd-weight-bold: 700;

  /* ---------------------------------------------------------------------
     TYPOGRAPHY - LINE HEIGHT
     Display lines are set tight (0.90-0.95 in Manon's own h1-h3); body is
     1.62-1.65. Unitless throughout, so they scale with font-size.
     --------------------------------------------------------------------- */
  --lfd-leading-flat: 0.9;
  --lfd-leading-display: 0.94;
  --lfd-leading-tight: 1.05;
  --lfd-leading-snug: 1.2;
  --lfd-leading-label: 1.35;
  --lfd-leading-body: 1.62;
  --lfd-leading-relaxed: 1.75;

  /* ---------------------------------------------------------------------
     TYPOGRAPHY - LETTER SPACING
     Two coherent intents in the canonical CSS, expressed through six
     near-identical values: tracked-out uppercase labels (0.08 / 0.12 / 0.13 /
     0.14em) and tightened display headlines (-0.045 / -0.065em). 0.13em is
     the most used and becomes the label default; 0.18em and 0.28em are real
     wider steps from the prototype's season bar and board labels.
     --------------------------------------------------------------------- */
  --lfd-tracking-display-tight: -0.065em;
  --lfd-tracking-display: -0.045em;
  --lfd-tracking-snug: -0.02em;
  --lfd-tracking-none: 0;
  --lfd-tracking-label-sm: 0.08em;
  --lfd-tracking-label: 0.13em;
  --lfd-tracking-label-lg: 0.18em;
  --lfd-tracking-label-xl: 0.28em;

  /* ---------------------------------------------------------------------
     SPACE
     A 4px-based scale for component-internal spacing, plus fluid tokens for
     the rhythms that are already fluid in the canonical design:
     section padding clamp(44px, 5vw, 84px) and column gap
     clamp(20px, 2.4vw, 38px).
     --------------------------------------------------------------------- */
  --lfd-space-3xs: 0.25rem;  /*  4px */
  --lfd-space-2xs: 0.5rem;   /*  8px */
  --lfd-space-xs: 0.75rem;   /* 12px */
  --lfd-space-sm: 1rem;      /* 16px */
  --lfd-space-md: 1.5rem;    /* 24px */
  --lfd-space-lg: 2rem;      /* 32px */
  --lfd-space-xl: 3rem;      /* 48px */
  --lfd-space-2xl: 4rem;     /* 64px */
  --lfd-space-3xl: 5.5rem;   /* 88px */
  --lfd-space-4xl: 7.5rem;   /* 120px */

  --lfd-space-section: clamp(2.75rem, 1.5rem + 5vw, 5.25rem);   /* 44-84px */
  --lfd-space-section-lg: clamp(4rem, 2rem + 7.5vw, 8rem);      /* 64-128px */
  --lfd-space-gap: clamp(1.25rem, 0.8rem + 2.4vw, 2.375rem);      /* 20-38px */
  --lfd-space-gap-lg: clamp(2rem, 1.2rem + 3vw, 3.25rem);       /* 32-52px */

  /* ---------------------------------------------------------------------
     WIDTH AND GUTTER
     The canonical LFD container is min(1560px, calc(100% - 56px)) - a 1560px
     line with a 28px gutter each side (lfd-menu.css, the header row). Manon's
     own grid is 1100px, which is what existing page content is built inside,
     so both are tokens: --lfd-width-content matches existing content, and
     --lfd-width-wide is the LFD editorial line.
     --------------------------------------------------------------------- */
  --lfd-space-gutter: 1.75rem;                                   /* 28px, canonical */
  --lfd-space-gutter-sm: 1.25rem;                                /* 20px on phones  */

  /* THE LFD PAGE SHELL'S GUTTERS, which are not the same three numbers.
     42 / 28 / 16 at desktop / 1180 / 767 - the approved measurements for the
     full-width LFD surfaces, as distinct from the 28/20 pair above that the
     existing .lfd-container uses. Two scales because there are two things:
     Manon's boxed content, and the shell the LFD surfaces run in. Declared
     here rather than in page-shell.css so there is one token layer. */
  --lfd-space-page-gutter: 2.625rem;                             /* 42px, desktop   */
  --lfd-space-page-gutter-md: 1.75rem;                           /* 28px, <= 1180   */
  --lfd-space-page-gutter-sm: 1rem;                              /* 16px, <= 767    */
  --lfd-width-text: 68ch;                                  /* reading measure */
  --lfd-width-content: 68.75rem;                           /* 1100px - Manon's grid */
  --lfd-width-wide: 97.5rem;                               /* 1560px - LFD canonical */
  --lfd-width-rail: 16.25rem;                              /* 260px - the sticky rail */
  --lfd-width-rail-lg: 20rem;                              /* 320px - collection rail */

  /* ---------------------------------------------------------------------
     RADIUS
     G1 - DECIDED, APPROVED as EDITORIAL GEOMETRY. Not "everything square" and
     not "everything pill". Geometry follows ROLE:

       surfaces  - images, editorial cards, large panels, primary layout
                   surfaces: square, or a restrained radius where the panel
                   genuinely calls for one
       controls  - CTA buttons, filters, chips, availability and status,
                   ticket-type controls: pills where the approved visual
                   language calls for them

     The scale below is the raw vocabulary. The ROLE tokens under it are what a
     component should actually use, so the decision lives in one place rather
     than being re-made at every call site. No global border-radius is applied
     to any legacy component - the design system targets no legacy class at
     all, and tests/test_design_system.py asserts it.
     --------------------------------------------------------------------- */
  --lfd-radius-none: 0;
  --lfd-radius-sm: 7px;
  --lfd-radius-md: 12px;
  --lfd-radius-lg: 22px;
  --lfd-radius-xl: 30px;
  --lfd-radius-pill: 999px;
  --lfd-radius-circle: 50%;

  /* Role tokens - what components use. Changing the language means changing
     these four lines, not auditing every component. */
  --lfd-radius-surface: var(--lfd-radius-none);   /* images, cards, panels, layout */
  --lfd-radius-panel: var(--lfd-radius-md);       /* a panel that earns a radius   */
  --lfd-radius-action: var(--lfd-radius-none);    /* CTA buttons - square          */
  --lfd-radius-control: var(--lfd-radius-pill);   /* chips, filters, status        */
  --lfd-radius-mark: var(--lfd-radius-circle);    /* monogram, avatar, social      */

  /* ---------------------------------------------------------------------
     BORDER
     --------------------------------------------------------------------- */
  --lfd-border-hairline: 1px;
  --lfd-border-thick: 2px;
  --lfd-border-rule: var(--lfd-border-hairline) solid var(--lfd-color-rule);
  --lfd-border-line: var(--lfd-border-hairline) solid var(--lfd-color-line);
  --lfd-border-soft: var(--lfd-border-hairline) solid var(--lfd-color-line-soft);
  --lfd-border-on-dark: var(--lfd-border-hairline) solid var(--lfd-color-line-on-dark);

  /* ---------------------------------------------------------------------
     SHADOW
     The canonical design has essentially one: a wide, very soft lift used on
     the news panel. Everything else is hairlines. That restraint is the design.
     --------------------------------------------------------------------- */
  --lfd-shadow-none: none;
  --lfd-shadow-lift: 0 24px 70px rgb(0 0 0 / 0.06);
  --lfd-shadow-raise: 0 10px 30px rgb(0 0 0 / 0.08);
  --lfd-shadow-focus: 0 0 0 3px var(--lfd-color-focus);

  /* ---------------------------------------------------------------------
     Z-INDEX
     53 declarations, 18 distinct values, running -1, 0, 1 ... 9998, 9999,
     99998, 99999, 100000, 100001, 999999. There is no scale - the top values
     are an escalation war with Manon and the admin bar.

     This is a scale. New components use only these names. Untangling the
     legacy values is a separate, later change with its own commit.
     --------------------------------------------------------------------- */
  --lfd-z-under: -1;
  --lfd-z-base: 0;
  --lfd-z-raised: 1;
  --lfd-z-sticky: 20;
  --lfd-z-header: 60;
  --lfd-z-dropdown: 70;
  --lfd-z-overlay: 80;
  --lfd-z-drawer: 90;
  --lfd-z-modal: 100;
  --lfd-z-toast: 110;
  --lfd-z-skip-link: 120;

  /* ---------------------------------------------------------------------
     MOTION
     The measured tokens are 0.18s (14 uses) and 0.25s (10 uses), with
     0.55-0.75s for editorial emphasis and 18-25s for the continuous outlined
     marquees. The Brand Book's 120/220/420ms was documented but never
     implemented; the implementation wins.

     The canonical CSS contains ZERO custom easings - everything is `ease`.
     --lfd-ease-standard is the accepted C v2 prototype curve and is what new
     components use; --lfd-ease-legacy exists so a legacy value can be matched
     deliberately rather than by accident.
     --------------------------------------------------------------------- */
  --lfd-duration-instant: 0ms;
  --lfd-duration-fast: 180ms;
  --lfd-duration-base: 250ms;
  --lfd-duration-slow: 550ms;
  --lfd-duration-editorial: 750ms;
  /* 33.3s, not 22s. The 22s here was taken from the audit's "18-25s loops",
     which were a regex artefact reading ".22s" as "22s" - a figure that never
     existed. The real speed is the vendor loop's 0.05% of a copy-width per
     frame (assets/js/modules.js:5949), which is 100/0.05 = 2000 frames, or
     33.3s at 60Hz. The approved instance of this is the ghost component; this
     token is what a general-purpose .lfd-marquee inherits. */
  --lfd-duration-marquee: 33.3s;

  --lfd-ease-standard: cubic-bezier(0.22, 1, 0.36, 1);
  --lfd-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --lfd-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --lfd-ease-legacy: ease;
  --lfd-ease-linear: linear;

  /* The contract a new component writes instead of a bespoke transition.
     Under prefers-reduced-motion these collapse - see motion.css - so a
     component that uses them needs no reduced-motion rule of its own. */
  --lfd-transition-fast: var(--lfd-duration-fast) var(--lfd-ease-standard);
  --lfd-transition-base: var(--lfd-duration-base) var(--lfd-ease-standard);
  --lfd-transition-slow: var(--lfd-duration-slow) var(--lfd-ease-standard);

  /* ---------------------------------------------------------------------
     BREAKPOINTS
     112 media-query width conditions across 52 distinct values, of which the
     genuine working set is four: 520, 767, 1024, 1180. The 980/981 and
     1024/1025 pairs are off-by-one duplicates of one intent.

     Custom properties CANNOT be used in a media query. These exist so that
     JavaScript and container queries read the same numbers the stylesheets
     do; media queries in this layer use the literals, and say so.
     --------------------------------------------------------------------- */
  --lfd-bp-xs: 520px;
  --lfd-bp-sm: 767px;
  --lfd-bp-md: 1024px;
  --lfd-bp-lg: 1180px;
  --lfd-bp-xl: 1560px;
}
