/* ==========================================================================
   Shared design language for every app in the portal.
   --------------------------------------------------------------------------
   Apps live in separate repos and run in separate frames, so their LAYOUT is
   isolated by design -- one app's CSS can never reach another's. This file is
   the deliberate exception: the vocabulary they all speak, so isolation
   doesn't turn into drift.

   IT IS COPIED, NOT LINKED. Each app keeps its own copy so it stays
   independently deployable and can be removed without breaking anything else.
   The cost is that a palette change means updating each app; that is the
   price of the apps not being able to break each other, and it is the right
   trade for a file that changes a few times a year.

   Nothing here should describe layout; only the raw materials.
   ========================================================================== */

/* LIGHT MODE IS DELIBERATELY NOT WHITE.
   ------------------------------------------------------------------------
   It used to be: --bg #fbfbfd and --panel pure #ffffff. Measured, that put the
   whole screen at 96.6% of white luminance with body text at 17:1 -- more than
   twice what WCAG AAA asks for. Maximum contrast is not maximum legibility;
   black on white at full brightness is the standard recipe for eye strain over
   anything longer than a paragraph, and it is worse for readers with
   astigmatism, where it produces visible halation around letterforms.

   The three problems were separate:
     screen luminance   96.6% -> 87.1%   paper, not a lightbulb
     text on panel      17.03 -> 13.03   still well past AAA (7:1)
     panel vs bg         1.03 ->  1.09   cards were invisible against the page,
                                         so they added glare without reading as
                                         raised. Now they separate.
   And the one that was genuinely too LOW went up:
     muted on panel      4.83 ->  5.87   secondary text was scraping the AA
                                         floor while the primary text blazed.

   The ground is very slightly warm rather than blue-white, which is easier to
   sit with -- but only slightly, because the accent is cyan and a properly warm
   page would fight it.

   Dark mode is untouched. Its ratios were already fine; the problem was never
   the ratio, it was the absolute brightness behind it. */
:root {
  /* Surfaces */
  --bg: #f1f0ed;          /* the page behind everything */
  --panel: #fafaf8;       /* raised cards sitting on it */
  --chip: #e8e7e3;        /* recessed fills: pills, bars, inputs */
  --border: #dcdad5;      /* hairlines; never a colour, always neutral */

  /* Text */
  --text: #2a2e36;
  --muted: #5c626d;

  /* Meaning. Reserved for interactive state and data -- never for framing
     a container. If the accent is also drawing boxes, it stops meaning
     "this is live" or "look here".

     The palette cyan is #25e5f1, and it cannot do this job alone. Measured:
     white text on it is 1.55:1 and the same cyan used as *text* on the light
     background is 1.50:1 -- both far under the 4.5:1 that makes small text
     readable, and under the 3:1 a focus ring needs to be seen at all. It is a
     bright colour, and bright colours are fills, not inks.

     So it is split by job rather than fudged:

       --brand     the cyan itself, used as a filled surface
       --on-brand  what goes on top of that fill -- dark, at 10.4:1
       --accent    the same hue darkened enough to be read as text, drawn as a
                   border and seen as a focus ring on a pale page (4.59:1)

     In dark mode --accent becomes the brand cyan outright: against #0f1116 it
     measures 12.19:1 and needs no help. */
  --brand: #25e5f1;
  --on-brand: #04252a;
  --accent: #096c76;
  --pos: #0d7441;
  --neg: #be3229;

  /* Form */
  --radius: 11px;
  --radius-sm: 7px;
  --radius-pill: 999px;
  --shadow: 0 1px 2px rgba(16, 20, 30, .06), 0 4px 16px rgba(16, 20, 30, .05);
  --font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1116;
    --panel: #171a21;
    --chip: #1f242e;
    --border: #262b35;
    --text: #e7e9ee;
    --muted: #9aa1ad;
    /* On a dark ground the brand cyan needs no darkening -- it measures
       12.19:1 as text, so accent and brand are the same colour here. */
    --brand: #25e5f1;
    --on-brand: #04252a;
    --accent: #25e5f1;
    --pos: #3fbd7c;
    --neg: #f0685c;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 18px rgba(0, 0, 0, .28);
  }
}

/* An explicit choice beats the OS preference, in both directions. The shell's
   theme control sets data-theme on <html> and forwards it into every frame,
   so one toggle moves the whole portal. */
/* MUST MATCH THE :root BLOCK ABOVE, VALUE FOR VALUE.
   The light palette is written twice -- once as the default and once here for
   an explicit choice -- and the two are only related by somebody remembering.
   They were not: softening the defaults above changed nothing on screen,
   because the toggle sets data-theme and this block quietly won. If you edit
   one, edit both. */
:root[data-theme="light"] {
  --bg: #f1f0ed; --panel: #fafaf8; --chip: #e8e7e3; --border: #dcdad5;
  --text: #2a2e36; --muted: #5c626d;
  --brand: #25e5f1; --on-brand: #04252a; --accent: #096c76;
  --pos: #0d7441; --neg: #be3229;
  --shadow: 0 1px 2px rgba(16, 20, 30, .06), 0 4px 16px rgba(16, 20, 30, .05);
}
:root[data-theme="dark"] {
  --bg: #0f1116; --panel: #171a21; --chip: #1f242e; --border: #262b35;
  --text: #e7e9ee; --muted: #9aa1ad;
  --brand: #25e5f1; --on-brand: #04252a; --accent: #25e5f1;
  --pos: #3fbd7c; --neg: #f0685c;
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 18px rgba(0, 0, 0, .28);
}


/* THE LIGHT PAIR IS TUNED FOR --chip, NOT --panel.
   ------------------------------------------------------------------------
   These were #0f8a4d and #c8352b, solved against the card surface. On this site
   they are also the syntax colours for strings and numbers, and a code block
   sits on --chip, which is darker than --panel -- so the same ink measured 3.56
   and 4.24 there, both under the floor, while looking perfectly fine on
   everything else.

   Solved for the darker of the two surfaces instead:

                    on --chip   on --panel
       green #0d7441    4.73        5.59
       red   #be3229    4.61        5.46

   The rule this is an instance of: a colour is only "verified" against the
   surface it was measured on. Reuse it somewhere darker and the check has to be
   redone. */

* { box-sizing: border-box; }

/* COLOR-SCHEME: tell the browser what it is actually looking at.
   --------------------------------------------------------------------------
   Scrollbars, form controls and the default canvas are drawn by the browser,
   which decides how from `color-scheme` -- never declared here, so it fell back
   to the OS preference. Invisible while the page matched the OS. It stopped
   being invisible the moment "light" started meaning a DARK page: on a light
   system the browser kept painting light, chunky scrollbars over a dark page.

   Here the two agree, so each theme declares itself. Keep the value matched to
   the --bg in the SAME block rather than to the block's NAME: on Pick Heart the
   light theme paints a dark page and correctly declares `dark`. The property
   describes the surface, not the label. */
:root { color-scheme: light; }
@media (prefers-color-scheme: dark) { :root { color-scheme: dark; } }
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
