/* ===========================================================================
   Lingua design tokens
   ---------------------------------------------------------------------------
   The single source of truth for brand values shared by the website and the
   mobile app. Colours, radii, spacing and type — nothing else.

   Deliberately contains NO component or layout rules. Those legitimately differ
   between a content website with page chrome and an app shell, and trying to
   share them means one side spends its life overriding the other. What makes
   the two look like one product is the values below, not the rules.

   CANONICAL COPY: public/css/tokens.css
     - the website links it directly
     - the app needs its own copy, because Capacitor bundles its assets and has
       no network at boot. After changing this file:
           cp public/css/tokens.css mobile/www/css/tokens.css

   HOW TO USE
     New CSS: reach for var(--lg-…) instead of a literal.
     Existing CSS: a.css is 3,364 lines of hardcoded values and is NOT being
     converted in one go. Replace literals with tokens as you touch them.
     Nothing breaks in the meantime — an unused custom property costs nothing.

   VALUES
     Every value here was taken from a.css / a-dark.css as it stands, not
     invented. Where a.css disagrees with itself, the modal-v2 login/register
     panel wins: it is the newest work, it is already border-box and rem-based,
     and it is the design the app is aligning to.
   =========================================================================== */

:root {
    /* --- Brand ---------------------------------------------------------- */
    --lg-red: #e55853;              /* primary action, links, accents */
    --lg-red-hover: #d93c36;        /* .button-cta:hover */
    --lg-red-shadow: #94332f;       /* text-shadow under the CTA label */

    /* --- Text ----------------------------------------------------------- */
    --lg-text: #272727;             /* body */
    --lg-text-muted: #6b6b7b;       /* modal__forgot, modal__switch */
    --lg-text-soft: #544f4e;        /* button--white label */
    --lg-text-inverse: #ffffff;

    /* --- Surfaces ------------------------------------------------------- */
    /* Page ground. Warm off-white, not the neutral #f9f9f9 it replaced — same
       shift as the coral going to #e55853. The header is deliberately NOT on
       this token: .header .container stays #ffffff so the bar reads as a
       distinct surface floating above the page. */
    --lg-bg: rgb(252, 250, 246);    /* body, .main, content column */
    --lg-surface: #ffffff;          /* cards, inputs, modals */
    /* Subtle fills: the neutral badge, the icon circle on a card, the sheet
       number, an empty progress segment, a hover ground. Everything that is a
       shade rather than a surface.

       Warm, not the #f3f3f3 this was. That grey was taken from a.css before
       the page ground moved to cream, and a cool tint on a warm card is the
       one place the two temperatures meet on the same element - small, but it
       is why the badges looked slightly grubby next to everything else.

       Contrast is unchanged to two decimal places: muted text on it is 4.72:1
       (was 4.71), so nothing that passed before stops passing. */
    --lg-surface-alt: rgb(246, 243, 237);
    --lg-surface-muted: #eeeeee;    /* .form-error-message background */

    /* --- Borders -------------------------------------------------------- */
    /* Warm hairline, replacing the cool #eaecec that separated header, leader,
       sub-header and main. Sits with the cream ground rather than against it.
       NOTE: the 41 hardcoded #E8E8E8 borders in a.css are still the old cool
       grey - they were never on this token and are not converted yet. */
    --lg-border: rgb(230, 226, 221);
    --lg-border-input: #d6d6dd;     /* modal-v2 .input-text */
    --lg-border-strong: #dbdbdb;    /* .button:hover, select */

    /* --- Radii ---------------------------------------------------------- */
    /* 8px is the dominant radius in a.css (22 uses); 5px is what the primary
       CTA actually uses, so both are named rather than collapsed into one. */
    /* --- Shadows -------------------------------------------------------- */
    /* Shadow tone, as bare channels so it can be used at any alpha:
           box-shadow: 0 2px 8px rgba(var(--lg-shadow-rgb), 0.12);

       A warm brown, not grey and not black. The old shadows were light greys
       at high alpha (rgba(222,222,222,0.9) and friends), which paint a cool
       patch rather than darkening what is under them - obvious once the page
       ground went warm. Each converted shadow kept its geometry and had its
       alpha recomputed so the result lands on the same luminance it did
       before over rgb(252, 250, 246): only the hue moved.

       Call sites carry "120, 98, 72" as a var() fallback, so a stylesheet
       loaded without tokens.css still gets a shadow instead of none. */
    --lg-shadow-rgb: 120, 98, 72;

    /* --- Score / progress ----------------------------------------------- */
    /* Gold, for the medal reading - NOT the coral. On a ring red says "wrong",
       and a score measures progress, not a grade; low progress is where every
       learner starts. Coral already means "do this" (CTA, premium), so
       spending it here would weaken it. Coral = do this, gold = you did this.

       The track is a warm cream rather than grey: gold on #eeeeee looks like a
       stain, gold on its own tint looks like an unfilled medal.

       These three were worked out for the grammar prototype and lived inside
       GrammarOverview::styles() in lib/. Copied here so the lg layer owns them
       - lib/ is shared with public/ and cannot be edited from this tree. The
       two copies must stay in step until beta is promoted. */
    --lg-score: #E4B548;
    --lg-score-track: #F3E7CE;

    /* The greyer track. Started as the ring's alone: at a 12-unit stroke the
       cream above is so close to the card white that the unfilled part of the
       ring stops reading as a ring at all.

       The suggestion cards' 7px bars now take it too (.lg-card__track). The
       argument for leaving them cream was that their edges do the work of
       separating fill from track - true of the shape, but not of the reading:
       gold on cream is close enough in value that the empty part of a short
       bar looked like more fill, and a card at 30% read as further along than
       it was. The other bars on the page still use --lg-score-track; if they
       go grey too, this token stops being "the ring's" and the pair above
       should be renamed rather than left saying something half-true.

       Same value as --lg-border rather than a new colour: the ring track and
       the hairlines are both "the quiet structural line", and tying them
       together means the warmth stays in step if either is retuned. */
    --lg-score-ring-track: rgb(230, 226, 221);

    /* Text needs its own value: #E4B548 is 1.91:1 on white, fine as a thick
       stroke and unreadable as a label. #977016 is the same hue at 4.52:1,
       which passes AA. Anything gold that is TEXT uses this. */
    --lg-score-text: #977016;

    /* A wrong answer, in the question strip above a multiple-choice sheet.
       Gold marks a right answer there, so the wrong one needs its own mark.

       Not a red. It was the brand coral for a while and that was too loud for
       what it reports: a segment is three pixels of history, and a red one in
       a row of six shouted about the question the learner has already seen the
       answer to. This is --lg-score-ring-track darkened by about a tenth on
       the same warm hue, so a wrong answer reads as a dimmed, spent segment
       rather than as an alarm.

       The shade is the whole signal - 226.5 against 195.8 relative lightness,
       a clear step down from a segment not yet reached. It briefly carried a
       small x on top, which at eight pixels was a speck that drew the eye
       without earning it.

       So this value has to keep its distance from --lg-score-ring-track above
       on LIGHTNESS and not on hue: the two are the same warmth by design, and
       a reader who cannot separate them by weight cannot separate them at
       all. */
    --lg-answer-wrong: rgb(201, 195, 188);

    /* --- The single-sheet column ---------------------------------------- */
    /* How wide one sheet is allowed to get, and the gutter inside that width.

       Everything on a sheet shares it: the one question on screen, the stepper
       above it, and the result card with its two suggestion lists - which is
       the point. They are the same sheet at three moments, they appear in the
       same place one after the other, and a column that changed width between
       them would read as the page jumping rather than as the work moving on.

       It is the measure itself, with no gutter inside it - both consumers set
       their own side padding to 0, so 748 is what the content actually comes
       out at. Anything that caps itself with this and then adds padding will
       end up narrower than everything else using it, which is the one mistake
       this token exists to prevent.

       Below 748 the cap stops applying and the column is whatever the
       container gives it, edge to edge. If a side gutter is wanted on a phone
       it belongs on .container, once, rather than on each of these.

       Not a max-width for the PAGE. The sticky exercise head above spans the
       full container on purpose, the way the result screen already has it. */
    --lg-column-max: 748px;

    --lg-radius: 8px;
    --lg-radius-cta: 5px;
    --lg-radius-sm: 6px;
    --lg-radius-lg: 10px;

    /* The lg layer's cards - score card, suggestion card, topic card. A new
       value rather than a reuse of --lg-radius-lg above, which is a.css's
       largest corner and still means that.

       calc() rather than a flat 19px so the corner tracks the type scale: the
       1rem half grows with the root font size, the 4px half does not, which
       keeps the curve in proportion on a card whose padding is in rem without
       letting it turn into a pill at large text sizes. */
    --lg-radius-card: calc(1rem + 4px);

    /* --- Typography ----------------------------------------------------- */
    /* Two families, split by role. Faces are declared in css/fonts-brand.css,
       which the header loads before this file. Always reach for these tokens
       rather than naming "DM Sans" / "Outfit" directly, so the next rebrand is
       one edit here instead of a grep across a.css. */
    --lg-font: "DM Sans", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --lg-font-heading: "Outfit", "DM Sans", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
    /* Headings sit at 600 in a.css. Outfit runs 500-800, so display text can
       go heavier without loading anything new. */
    --lg-font-weight-heading: 600;
    --lg-line-height: 1.55;
    --lg-font-weight: 400;
    --lg-font-size-sm: 0.85rem;
    --lg-font-size-base: 1rem;
    --lg-font-size-lead: 0.95rem;   /* modal-v2 input font-size */

    /* Optical size correction for body copy.

       DM Sans has an x-height of 0.504 em; Open Sans, which it replaced, has
       0.535. Glyph height is what the eye reads as "text size", not the em
       box, so at an unchanged 15px DM Sans looks about 6% smaller than the
       site did before. 0.535 / 0.504 = 1.0618, rounded to 1.0625 (17/16).

       Deliberately em, not rem: a paragraph inside a component that has
       already scaled its own text down should keep that relationship and get
       the same 6% correction, not be yanked back up to the root size. */
    --lg-font-size-p: 1.0625em;     /* 15px -> 15.94px at the root */

    /* --- Controls ------------------------------------------------------- */
    --lg-control-padding: 0.8rem 1rem;   /* modal-v2 .input-text */
    --lg-cta-padding: 0.95rem 1.5rem;    /* modal-v2 .button-cta */
    /* Smallest comfortably tappable target on a phone. Not from a.css — the
       website has no such rule, and it is the one value here the app genuinely
       needs that the site never did. */
    --lg-tap-target: 44px;

    /* --- Feedback ------------------------------------------------------- */
    --lg-ok-bg: #e7f6ec;
    --lg-ok-text: #17603a;
    --lg-bad-bg: #fdecea;
    --lg-bad-text: #96271f;
}

/* ===========================================================================
   Dark theme
   ---------------------------------------------------------------------------
   Two triggers, on purpose:

     @media (prefers-color-scheme: dark)   follows the OS. What the app uses.
     [data-theme="dark"] / ="light"        explicit choice, overrides the OS.

   The website currently switches themes by enabling a whole second stylesheet
   (a-dark.css, toggled through `disabled` in header.php). When dark mode is
   added properly, that file can shrink to a token override block like the one
   below instead of re-declaring rules — same values, one place.

   Both selectors are needed. prefers-color-scheme alone gives no way for a user
   toggle to win against the OS, and a class alone means the app ignores the
   system setting until the user finds a switch. Values are from a-dark.css.

   ---------------------------------------------------------------------------
   FOLLOWING THE OS IS OFF AT THE MOMENT
   ---------------------------------------------------------------------------

   The website is half converted. The legacy side only goes dark when a-dark.css
   is enabled - it is linked with `disabled` in includes/header.php and switched
   on deliberately - so it does not follow the OS at all. This layer did, which
   meant a visitor whose system is set to dark got a page in two themes at once:
   the lg components dark, everything around them light.

   So the media block below no longer matches on its own. It is gated behind
   data-theme="auto", which nothing sets today.

   TO TURN IT BACK ON, either:

     for good     change the selector below from
                      :root[data-theme="auto"]
                  back to
                      :root:not([data-theme="light"])

     to try it    put data-theme="auto" on the <html> element - from the
                  console, or from header.php - and the OS setting takes over
                  again with no CSS change at all.

   Nothing else was touched. The values are all still here, and the explicit
   [data-theme="dark"] block further down still works, so the day the toggle is
   built it has something to switch.
   =========================================================================== */

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] {
        --lg-text: #e0e0e0;
        --lg-text-muted: #a8a8b4;
        --lg-text-soft: #cfcfcf;

        --lg-bg: #121212;
        --lg-surface: #2b2b2b;
        --lg-surface-alt: #2c2c2c;
        --lg-surface-muted: #333333;

        --lg-border: #444444;
        --lg-border-input: #555555;
        --lg-border-strong: #555555;

        --lg-ok-bg: #12351f;
        --lg-ok-text: #7ddba3;
        --lg-bad-bg: #3a1a17;
        --lg-bad-text: #f3a49c;
    }
}

/* Explicit choice. Repeated rather than shared with the block above because a
   media query and an attribute selector cannot be combined into one rule. */
:root[data-theme="dark"] {
    --lg-text: #e0e0e0;
    --lg-text-muted: #a8a8b4;
    --lg-text-soft: #cfcfcf;

    --lg-bg: #121212;
    --lg-surface: #2b2b2b;
    --lg-surface-alt: #2c2c2c;
    --lg-surface-muted: #333333;

    --lg-border: #444444;
    --lg-border-input: #555555;
    --lg-border-strong: #555555;

    --lg-ok-bg: #12351f;
    --lg-ok-text: #7ddba3;
    --lg-bad-bg: #3a1a17;
    --lg-bad-text: #f3a49c;
}

/* The brand red is intentionally NOT overridden for dark. It is the one value
   that must stay constant for the product to remain recognisable, and at
   #e55853 it already clears contrast on both #f9f9f9 and #121212. */
