/* ===========================================================================
   Sidelore Design System — tokens
   ---------------------------------------------------------------------------
   Source of truth: design_handoff_sidelore/README.md
     § Design tokens (colour, student surface + dark + parent surface)
     § Typography (the role table)
     § Layout and geometry
     § Focus and interaction states
   and sidelore-design-brief.md §2 (register, non-negotiables, type, colour,
   themes and motion).

   Rules encoded here, not negotiable:
     - border radius 0 everywhere
     - no red, no alarm hue: there is no error/failure colour in this system
     - no shadow, no elevation
     - two faces, load-bearing: Newsreader = writing, Archivo = apparatus
     - dark is first-class, not a filter over light

   Values are transcribed from the README tables verbatim. Where a token is
   marked DERIVED the README does not declare it for that theme; the
   derivation is stated so it can be replaced with an authored value.

   ---------------------------------------------------------------------------
   VALIDATION RULE FOR ANYTHING ADDED TO THIS FILE (brief §2.5a, doctrine)

     A palette validated only against ground colours will pass while every
     tinted surface in it fails.

   This is not hypothetical — it is how all three of the contrast defects
   found in this build got in. The handoff's dark muted #8E877C was chosen so
   its ratio ON THE GROUND (5.09:1) matched light muted's on paper (5.09:1).
   The pair was checked. It was checked against the wrong background: on the
   tinted ground it was 4.44:1 and every inset block in the product failed.
   The failing pair appears in neither of the handoff's tables, because the
   tint and the ink are declared in different rows and the composite is
   never written down anywhere.

   So when adding or changing any ink or any ground here, measure the ink
   against EVERY ground it can land on, not just the page ground:
     - the plain ground                    (--t-paper)
     - the tinted ground                   (--t-paper-tint)
     - every hover fill, which is the tint again and is TRANSIENT, so it
       will not show up in a static review
     - the accent fill, for anything that sits on it
   The preview has a "muted ink on tinted ground" specimen with the hover
   states forced on, for exactly this purpose. Use it.
   --------------------------------------------------------------------------- */

/* --- Faces ---------------------------------------------------------------
   Email fallback stack for Newsreader is Georgia first — that is the
   realistic rendering in most mail clients, and it is kept here so the app
   and the send agree when a font fails to load. */
:root {
  --t-face-writing: 'Newsreader', Georgia, 'Times New Roman', serif;
  --t-face-apparatus: 'Archivo', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
}

/* =====================  TYPE SCALE  =======================================
   Ranges in the README table are carried as two tokens rather than
   collapsed to one value. Nothing is rounded. */
:root {
  /* Hook — light. Overridden in the dark block: the hook is the one role
     whose size and weight are theme-dependent by specification. */
  --t-hook-size: 33px;
  --t-hook-weight: 400;
  --t-hook-lh: 1.18;
  --t-hook-tracking: -0.02em;

  /* Screen title — 27–30px / 400 / 1.22–1.25 / −0.015em */
  --t-screen-title-size: 27px;
  --t-screen-title-size-lg: 30px;
  --t-screen-title-weight: 400;
  --t-screen-title-lh: 1.25;
  --t-screen-title-lh-tight: 1.22;
  --t-screen-title-tracking: -0.015em;

  /* Reflection prompt — 24–29px / 400 / 1.24–1.28 / −0.015em */
  --t-prompt-size: 24px;
  --t-prompt-size-lg: 29px;
  --t-prompt-weight: 400;
  --t-prompt-lh: 1.28;
  --t-prompt-lh-tight: 1.24;
  --t-prompt-tracking: -0.015em;

  /* Argument paragraph — 18px / 400 / 1.55 */
  --t-argument-size: 18px;
  --t-argument-weight: 400;
  --t-argument-lh: 1.55;

  /* Reflection, displayed back to the student — 18.5px / 400 / 1.6–1.62.
     THE load-bearing rule: never UI grey, never a form field's styling. */
  --t-reflection-size: 18.5px;
  --t-reflection-weight: 400;
  --t-reflection-lh: 1.6;
  --t-reflection-lh-loose: 1.62;

  /* Reflection textarea — borderless, transparent, 19px / 1.6 */
  --t-reflection-field-size: 19px;
  --t-reflection-field-lh: 1.6;

  /* Coverage sentence — 17px / 400 / 1.45 */
  --t-coverage-size: 17px;
  --t-coverage-weight: 400;
  --t-coverage-lh: 1.45;

  /* List entry title — 19px / 400 / 1.35 */
  --t-list-title-size: 19px;
  --t-list-title-weight: 400;
  --t-list-title-lh: 1.35;

  /* Masthead — 20px / 500 / −0.02em */
  --t-masthead-size: 20px;
  --t-masthead-weight: 500;
  --t-masthead-tracking: -0.02em;

  /* Button / action — Archivo 14px / 600 */
  --t-action-size: 14px;
  --t-action-weight: 600;

  /* Body apparatus — Archivo 13px / 400 / 1.6 */
  --t-apparatus-size: 13px;
  --t-apparatus-weight: 400;
  --t-apparatus-lh: 1.6;

  /* Metadata — Archivo 12.5px / 400 / 1.55 */
  --t-metadata-size: 12.5px;
  --t-metadata-weight: 400;
  --t-metadata-lh: 1.55;

  /* Kicker / label — Archivo 11px / 400–600 / 0.12–0.14em / uppercase */
  --t-kicker-size: 11px;
  --t-kicker-weight: 400;
  --t-kicker-weight-strong: 600;
  --t-kicker-tracking: 0.12em;
  --t-kicker-tracking-wide: 0.14em;

  /* Text input — Archivo, 2px ink bottom rule, no box (brief §2.5a, decision 7).
     This is NOT the reflection field: that stays borderless, transparent and
     Newsreader per §2.4. They are deliberately different objects.
     AUTHORED size: the README role table has no input row, and 16px is the
     floor below which iOS zooms the viewport on focus, which would break the
     390 target. */
  --t-input-size: 16px;
  --t-input-lh: 1.5;

  /* Taxonomy label — Archivo 11px / 400 / 0.1em / uppercase / 2px top rule */
  --t-taxonomy-size: 11px;
  --t-taxonomy-weight: 400;
  --t-taxonomy-tracking: 0.1em;
  --t-taxonomy-rule: 2px;
}

/* =====================  SPACING, GEOMETRY  ================================
   Rhythm 4 / 8 / 12 / 16 / 24 / 32. Prefer gap over sibling margins.

   NOTE FOR ANYONE COMPARING THIS AGAINST THE PROTOTYPE. The .dc.html file
   uses 22 / 26 / 30 / 17 / 15 / 13 / 9 / 7px in places. That is eyeball
   drift, not intent, and the rhythm is the specification (brief §2.5a,
   decision 4). Spacing here is snapped to the rhythm deliberately. Do NOT
   "correct" it back from the prototype. Type values are the opposite case:
   they are transcribed exactly and must not be snapped to anything. */
:root {
  --t-space-1: 4px;
  --t-space-2: 8px;
  --t-space-3: 12px;
  --t-space-4: 16px;
  --t-space-5: 24px;
  --t-space-6: 32px;

  --t-page-padding: 24px;

  /* Border radius 0 everywhere. Never round a corner. */
  --t-radius: 0;

  --t-rule-major: 2px;   /* between major sections, solid ink */
  --t-rule-minor: 1px;   /* between list items, hairline */

  /* The colour of a 2px major rule, kept as its own token so the answer is
     in one place.

     IMPORTANT, AND THE THING THAT HAS ALREADY CAUSED DRIFT: a major rule is
     SOLID INK in both themes -- #1F1D1B on paper, #EDE8DF on the dark
     ground. It is not a translucent white. The README's dark
     rgba(255,255,255,0.18 / 0.14) pair are the MINOR and hairline rules
     only; the dark prototype never draws a 2px major rule, which is why
     the handoff looks as though it declares one and does not.

     Solid ink gives 15.04:1 in light and 14.82:1 in dark -- the two themes
     carry the same structural weight, which is the point. A 2px rule at
     0.18 is 1.74:1 (invisible as structure, and a WCAG 1.4.11 failure);
     at 0.34 it is 3.11:1, still a fifth of the light weight.

     The VALUE is declared in each colour block below, not here, and that is
     deliberate -- see the note on indirect tokens at the top of the colour
     section. Declaring it once here as var(--t-ink) silently froze it to
     the light ink in every theme, which made the dark major rule #1F1D1B
     on a #171614 ground: invisible. */

  /* Coverage grid: 96px sans label gutter, serif sentence in the field. */
  --t-coverage-gutter: 96px;

  /* 390×844 design target, 360 floor. Desktop is a scaled reading view. */
  --t-screen-width: 390px;
  --t-screen-height: 844px;
  --t-screen-min: 360px;

  /* Focus. Literal from the README's CSS block in light; the dark blocks
     below override the colour -- see the note there. */
  --t-focus-width: 2px;
  --t-focus-colour: #9A5B3F;
  --t-focus-offset: 2px;
}

/* ===========================================================================
   INDIRECT TOKENS MUST BE REDECLARED IN EVERY COLOUR BLOCK.

   A custom property whose value contains var() is substituted at
   computed-value time ON THE ELEMENT WHERE IT IS DECLARED, and what
   inherits downward is the resolved literal. So this, declared once on
   :root, does NOT re-resolve per theme:

       :root { --t-rule-major-colour: var(--t-ink); }   <-- WRONG

   It freezes to the light ink and every theme below gets #1F1D1B —
   which made the dark 2px major rule near-black on a near-black ground.
   It rendered as nothing, and it is the most structural element in the
   system.

   Every token here defined in terms of another token is therefore
   declared in all four colour scopes: light, the prefers-colour-scheme
   dark block, [data-theme='dark'], and [data-surface='parent']. That is
   --t-q1-marker, --t-q3-marker, --t-chip-fill-on, --t-chip-text-on and
   --t-rule-major-colour. If you add another, declare it four times or
   give it a literal value.
   =========================================================================== */

/* =====================  COLOUR — STUDENT, LIGHT  ========================== */
:root,
[data-theme='light'] {
  color-scheme: light;

  --t-paper: #F5F2EC;              /* page ground */
  --t-paper-tint: #EFE9DF;         /* hover fills, inset blocks */
  --t-ink: #1F1D1B;                /* primary text, 2px rules, selected chip fill */
  --t-ink-secondary: #3A3632;      /* argument paragraphs, inset-block body */
  --t-ink-muted: #6B665F;          /* metadata, labels, kickers. 5.09:1 on paper.
                                      WARNING: on --t-paper-tint (#EFE9DF) this is
                                      4.71:1 — it passes AA, but with only 0.21 of
                                      headroom. Darkening the light tint pushes muted
                                      text inside every inset block and every hover
                                      fill below the 4.5 floor. Re-measure this pair
                                      before touching --t-paper-tint. */
  --t-rule-hairline: rgba(31, 29, 27, 0.22);
  --t-rule: rgba(31, 29, 27, 0.22);
  --t-rule-strong: rgba(31, 29, 27, 0.3);   /* the S5 time-divider hairlines */
  --t-rule-chip: rgba(31, 29, 27, 0.3);     /* unselected chip border */

  --t-accent: #9A5B3F;             /* clay. This week's item, interactive. Nothing else. */
  --t-accent-pressed: #83492F;     /* primary button hover */
  --t-accent-text: #6E3B25;        /* links and accent body copy. Clears AA at paragraph size */
  --t-on-accent: #FFF8F2;          /* text on the clay fill */

  --t-q1-marker: var(--t-accent);  /* Q1 taxonomy 2px top rule */
  --t-q2-marker: #6B6A30;          /* olive, Q2 taxonomy 2px top rule only */
  --t-q3-marker: var(--t-ink);     /* DECIDED (brief §2.5a, decision 3): clay / olive /
                                      ink is a quiet descending emphasis. Three coloured
                                      markers would make the taxonomy the row of badges
                                      P4 exists to forbid. */

  --t-chip-fill-on: var(--t-ink);
  --t-chip-text-on: var(--t-paper);
  --t-rule-major-colour: var(--t-ink);
}

/* =====================  COLOUR — STUDENT, DARK  ===========================
   First-class. A phone used in bed at 11pm. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;

    --t-paper: #171614;
    --t-paper-tint: rgba(237, 232, 223, 0.06); /* DERIVED: README declares no dark
                                                  tint. Dark ink at 6% rather than a
                                                  new hex.

                                       DO NOT RAISE THIS ALPHA ABOVE 0.06 WITHOUT
                                       RE-MEASURING MUTED ON TINT (brief §2.5a,
                                       decision 11). It composites to rgb(35.8,
                                       34.6, 32.2) and the whole muted-text result
                                       below depends on that composite. Measured
                                       headroom for --t-ink-muted #948D82:
                                         0.06 -> 4.80:1  (shipped)
                                         0.07 -> 4.68:1
                                         0.08 -> 4.55:1  (last alpha that clears)
                                         0.09 -> 4.43:1  FAILS AA
                                       Lightening the tint to fix anything else
                                       breaks metadata inside every inset block. */
    --t-ink: #EDE8DF;
    --t-ink-secondary: #CFC8BC;

    /* AUTHORED (brief §2.5a, decision 11). The handoff's #8E877C is 5.09:1 on the
       dark ground — deliberately matched to light muted's 5.09:1 on paper, which is
       exactly why the real failure went unseen: the failing pair never appears in
       either of the handoff's tables. On --t-paper-tint it is 4.44:1, under the 4.5
       floor, and §2 puts muted text inside tinted insets by name (the Honest No, the
       sensitive-category privacy offer), so every tinted inset and every hover fill
       in the product was failing.

       #948D82 is 4.80:1 on tint and 5.50:1 on ground. It is deliberately the MINIMAL
       correction that clears: muted's job is to recede, and over-lifting makes
       metadata compete with body text. Lifting muted is also the only direction that
       works — a heavier tint lightens the ground and makes it worse, a lighter one
       stops the inset reading as an inset. */
    --t-ink-muted: #948D82;
    --t-rule: rgba(255, 255, 255, 0.18);
    --t-rule-hairline: rgba(255, 255, 255, 0.14);
    --t-rule-strong: rgba(255, 255, 255, 0.18);
    --t-rule-chip: rgba(255, 255, 255, 0.3);   /* DERIVED: mirrors the light 0.3 */

    --t-accent: #C4866A;                       /* lifted from clay */
    --t-accent-pressed: #E4BBA6;               /* README: "Accent, hover" */
    --t-accent-text: #C4866A;                  /* DERIVED: the light value is a
                                                  darkened clay for AA on paper; on
                                                  the dark ground the accent itself
                                                  reads. */
    --t-on-accent: #171614;                    /* DERIVED: the lifted clay is light,
                                                  so text on it is the ground. */

    --t-q1-marker: var(--t-accent);
    --t-q2-marker: #ADAB66;                    /* AUTHORED (brief §2.5a, decision 2):
                                                  the olive lifted in the same
                                                  proportion as clay -> #C4866A.
                                                  7.6:1 on the dark ground. Authored,
                                                  not computed from the handoff --
                                                  it wants a design eye before ship. */
    --t-q3-marker: var(--t-ink);

    /* AUTHORED (brief §2.5a, decision 1): #9A5B3F on #171614 is 2.4:1 and a real
       WCAG 1.4.11 Non-text Contrast failure. The declared dark accent is ~6:1. */
    --t-focus-colour: #C4866A;

    /* The hook is 38px / 300 / 1.14 / −0.025em in dark — a specified role
       change, not a rendering artefact. */
    --t-hook-size: 38px;
    --t-hook-weight: 300;
    --t-hook-lh: 1.14;
    --t-hook-tracking: -0.025em;

    --t-chip-fill-on: var(--t-ink);
    --t-chip-text-on: var(--t-paper);
    --t-rule-major-colour: var(--t-ink);
  }
}

[data-theme='dark'] {
  color-scheme: dark;

  --t-paper: #171614;
  --t-paper-tint: rgba(237, 232, 223, 0.06); /* do not raise above 0.06 — see the
                                                prefers-colour-scheme block above */
  --t-ink: #EDE8DF;
  --t-ink-secondary: #CFC8BC;
  --t-ink-muted: #948D82; /* AUTHORED — see the prefers-colour-scheme block above */
  --t-rule: rgba(255, 255, 255, 0.18);
  --t-rule-hairline: rgba(255, 255, 255, 0.14);
  --t-rule-strong: rgba(255, 255, 255, 0.18);
  --t-rule-chip: rgba(255, 255, 255, 0.3);

  --t-accent: #C4866A;
  --t-accent-pressed: #E4BBA6;
  --t-accent-text: #C4866A;
  --t-on-accent: #171614;

  --t-q1-marker: var(--t-accent);
  --t-q2-marker: #ADAB66;   /* AUTHORED -- see the prefers-colour-scheme block above */
  --t-q3-marker: var(--t-ink);

  --t-focus-colour: #C4866A; /* AUTHORED -- see the prefers-colour-scheme block above */

  --t-hook-size: 38px;
  --t-hook-weight: 300;
  --t-hook-lh: 1.14;
  --t-hook-tracking: -0.025em;

  --t-chip-fill-on: var(--t-ink);
  --t-chip-text-on: var(--t-paper);
  --t-rule-major-colour: var(--t-ink);
}

/* =====================  COLOUR — PARENT SURFACE  ==========================
   Cooler, and NO clay accent anywhere. The accent means "this week's item"
   and "interactive", and neither applies to a parent. Apply with
   data-surface="parent" on the shell. */
[data-surface='parent'] {
  --t-paper: #FAF8F4;
  --t-paper-outer: #E9E6E0;        /* email outer ground — a different job, stays */

  /* DECIDED (brief §2.5a, decision 12): THE PARENT SURFACE HAS NO TINT.
     Insets here are a 2px left rule with no fill; see .t-inset in the
     components file.

     Every value fix for the 4.12:1 muted-on-tint failure was bad — darkening
     the tint converges it with the text, lightening it until muted clears
     makes it indistinguishable from the ground, and darkening muted far
     enough to be safe drifts a long way from a declared value. That is the
     shape of a problem that should not be solved at the value layer. §2
     already says alignment and rule weight do all the organising, so a ruled
     inset is the more faithful component anyway: the contrast pair ceases to
     exist rather than being managed, and #726D65 stays exactly as declared.

     It is set to transparent rather than removed. Removing the declaration
     would inherit the student light tint #EFE9DF, which is both a warm fill
     on a cool ground and still a failure at 4.25:1.

     CONSEQUENCE, ACCEPTED: this also removes hover fills on the parent
     surface, since they are the same token. That surface is email-primary
     with barely any hover, and focus states are unaffected. */
  --t-paper-tint: transparent;
  --t-ink: #232120;
  --t-ink-secondary: #3A3632;
  --t-ink-secondary-alt: #4A4641;
  --t-ink-muted: #726D65;          /* 4.84:1 on the ground — do not lighten */

  /* RESOLVED (brief §2.5a, decision 12) — structurally, not by moving this
     value. #726D65 on the old parent tint #E9E6E0 was 4.12:1, a worse AA
     failure than the 4.44:1 that raised decision 11. Rather than darken this
     declared value, the tint was removed from this surface entirely (see
     --t-paper-tint above): with no fill, muted only ever lands on the plain
     ground at 4.84:1 and the failing pair no longer exists. */
  --t-rule: #C9C2B6;
  --t-rule-hairline: rgba(58, 54, 50, 0.22);
  --t-rule-strong: rgba(58, 54, 50, 0.3);
  --t-rule-chip: rgba(58, 54, 50, 0.3);

  /* The one button. There is no accent on this surface. */
  --t-accent: #3A3632;
  --t-accent-pressed: #232120;
  --t-accent-text: #3A3632;
  --t-on-accent: #FAF8F4;

  /* AUTHORED (brief §2.5a, decision 10): the focus ring is #3A3632 here, not
     clay. "No clay anywhere" on the parent surface was meant literally, and
     #3A3632 is already this surface's only interactive fill, so the ring
     speaks the surface's own interactive language rather than importing a
     second one. The cross-surface consistency argument is weak here because
     the parent surface is email-primary and has almost no keyboard
     interaction to be consistent about. ~11:1 on the parent ground, so this
     is doctrine rather than accessibility. */
  --t-focus-colour: #3A3632;

  --t-q1-marker: var(--t-ink-secondary);
  --t-q2-marker: var(--t-ink-muted);
  --t-q3-marker: var(--t-ink-secondary);

  --t-chip-fill-on: var(--t-ink-secondary);
  --t-chip-text-on: #FAF8F4;
  --t-rule-major-colour: var(--t-ink);
}
