/* ── Browser support ─────────────────────────────────────────────────────────
   WebKit 16.2 and newer, and current Chrome, Edge and Firefox.

   There is no autoprefixer. The vendor prefixes still in this project are the
   ones with no working unprefixed equivalent at that floor. Do not remove one
   because an unprefixed property sits beside it.

   ui/test/vendor-prefix-ratchet.test.mjs holds the permitted list. */

/* ── Palette ─────────────────────────────────────────────────────────────────
   Dark values. Each hue has a -hi partner, the increased-contrast value used by
   the prefers-contrast block below. The light theme re-declares both further
   down. */
:root {
  --sy-red:#FF4245;      --sy-red-hi:#FF6165;
  --sy-orange:#FF9230;   --sy-orange-hi:#FFA056;
  --sy-yellow:#FFD600;   --sy-yellow-hi:#FEDF43;
  --sy-green:#30D158;    --sy-green-hi:#4AD968;
  --sy-mint:#00DAC3;     --sy-mint-hi:#54DFCB;
  --sy-teal:#00D2E0;     --sy-teal-hi:#3BDDEC;
  --sy-cyan:#3CD3FE;     --sy-cyan-hi:#6DD9FF;
  --sy-blue:#0091FF;     --sy-blue-hi:#5CB8FF;
  --sy-indigo:#6D7CFF;   --sy-indigo-hi:#A7AAFF;
  --sy-purple:#DB34F2;   --sy-purple-hi:#EA8DFF;
  --sy-pink:#FF375F;     --sy-pink-hi:#FF8AC4;
  --sy-brown:#B78A66;    --sy-brown-hi:#DBA679;

  /* gray6 is the darkest, gray the lightest. The light theme reverses this. */
  --sy-gray:#8E8E93;     --sy-gray-hi:#AEAEB2;
  --sy-gray2:#636366;    --sy-gray2-hi:#7C7C80;
  --sy-gray3:#48484A;    --sy-gray3-hi:#545456;
  --sy-gray4:#3A3A3C;    --sy-gray4-hi:#444446;
  --sy-gray5:#2C2C2E;    --sy-gray5-hi:#363638;
  --sy-gray6:#1C1C1E;    --sy-gray6-hi:#242426;

  /* Not palette values. Each is the lift off gray and gray2 that clears WCAG on
     the card surface, gray4. Lowering either fails ui/test/contrast.test.mjs. */
  --sy-a11y-dim:#A3A3A8;
  --sy-a11y-border:#838387;
}

/* ── Roles ───────────────────────────────────────────────────────────────────
   What a colour is for. A rule names a role, never a palette entry. */
:root {
  --accent:        var(--sy-teal);
  --accent-strong: var(--sy-teal-hi);
  --danger:        var(--sy-red);
  --warning:       var(--sy-orange);
  --success:       var(--sy-green);

  /* Ink on a filled control. White in both themes. Not a label level: the text
     ramp would turn it black in the light theme. */
  --on-accent:     #FFFFFF;

  --sy-radius-lg:14px;
  --sy-radius-md:10px;
  --sy-radius-group:26px;
}

/* ── Semantic colour ─────────────────────────────────────────────────────────
   What a colour is applied to, dark values. See docs/design-system.md.

   Label levels below primary do not clear WCAG on this project's cards. Text
   that has to be read on a card uses --sy-a11y-dim.

   Fills are not the dashboard's glass. The glass is white at low alpha over a
   wallpaper; a fill is grey-tinted and assumes an opaque surface. */
:root {
  --label-primary:     #FFFFFF;
  --label-secondary:   rgba(235,235,245,.70);
  --label-tertiary:    rgba(235,235,245,.30);
  --label-quaternary:  rgba(235,235,245,.16);

  --fill-primary:      rgba(120,120,128,.36);
  --fill-secondary:    rgba(120,120,128,.32);
  --fill-tertiary:     rgba(118,118,128,.24);
  --fill-quaternary:   rgba(118,118,128,.18);

  --separator-opaque:  #38383A;
  --separator:         rgba(255,255,255,.17);

  --bg-primary:        #000000;
  --bg-secondary:      var(--sy-gray6);
  --bg-tertiary:       var(--sy-gray5);
  --bg-elevated-primary:   var(--sy-gray6);
  --bg-elevated-secondary: var(--sy-gray5);
  --bg-elevated-tertiary:  var(--sy-gray4);

  /* The opt-in light widget card. */
  --bg-primary-light:  #FFFFFF;

  /* A slider or switch knob. Full white in both themes, so not a label. */
  --control-knob:      #FFFFFF;
}

/* ── Light theme ─────────────────────────────────────────────────────────────
   The same sets at their light values, selected by an attribute a page sets on
   <html>. No stylesheet declares a prefers-color-scheme rule.

   Light hues are drawn for a fill, not for text. A role that ends up as text or
   as the edge of a control points at the -hi entry, the accessible variant of
   the same hue. ui/test/contrast.test.mjs measures the required pairs. */
html[data-theme="light"] {
  --sy-red:#FF3B30;      --sy-red-hi:#D70015;
  --sy-orange:#FF9500;   --sy-orange-hi:#C93400;
  --sy-yellow:#FFCC00;   --sy-yellow-hi:#B25000;
  --sy-green:#34C759;    --sy-green-hi:#248A3D;
  --sy-mint:#00C7BE;     --sy-mint-hi:#0C817B;
  --sy-teal:#30B0C7;     --sy-teal-hi:#0071A4;
  --sy-cyan:#32ADE6;     --sy-cyan-hi:#007AA3;
  --sy-blue:#007AFF;     --sy-blue-hi:#0040DD;
  --sy-indigo:#5856D6;   --sy-indigo-hi:#3634A3;
  --sy-purple:#AF52DE;   --sy-purple-hi:#8944AB;
  --sy-pink:#FF2D55;     --sy-pink-hi:#C9155A;
  --sy-brown:#A2845E;    --sy-brown-hi:#7F6545;

  /* Reversed: gray is the darkest here, gray6 the lightest. */
  --sy-gray:#8E8E93;     --sy-gray-hi:#6C6C70;
  --sy-gray2:#AEAEB2;    --sy-gray2-hi:#8E8E93;
  --sy-gray3:#C7C7CC;    --sy-gray3-hi:#AEAEB2;
  --sy-gray4:#D1D1D6;    --sy-gray4-hi:#BCBCC0;
  --sy-gray5:#E5E5EA;    --sy-gray5-hi:#D8D8DC;
  --sy-gray6:#F2F2F7;    --sy-gray6-hi:#EBEBF0;

  /* The greys above already clear WCAG on white, so no lift is needed here. */
  --sy-a11y-dim:var(--sy-gray-hi);
  --sy-a11y-border:var(--sy-gray);

  /* The accessible teal. The light teal carries neither white ink nor a link
     colour on white. */
  --accent:        var(--sy-teal-hi);
  --accent-strong: #00587E;
  --danger:        var(--sy-red-hi);
  --warning:       var(--sy-orange-hi);
  --success:       var(--sy-green-hi);

  --label-primary:     #000000;
  --label-secondary:   rgba(60,60,67,.60);
  --label-tertiary:    rgba(60,60,67,.30);
  --label-quaternary:  rgba(60,60,67,.18);

  --fill-primary:      rgba(120,120,128,.20);
  --fill-secondary:    rgba(120,120,128,.16);
  --fill-tertiary:     rgba(118,118,128,.12);
  --fill-quaternary:   rgba(116,116,128,.08);

  --separator-opaque:  #C6C6C8;
  --separator:         rgba(60,60,67,.29);

  --bg-primary:        #FFFFFF;
  --bg-secondary:      var(--sy-gray6);
  --bg-tertiary:       #FFFFFF;
  --bg-elevated-primary:   #FFFFFF;
  --bg-elevated-secondary: var(--sy-gray6);
  --bg-elevated-tertiary:  #FFFFFF;
}

/* ── Type scale ──────────────────────────────────────────────────────────────
   Eleven styles at the default step. A rule sets all three tokens of a style.

   Leading is unitless and tracking is in em, never px. Sizes are multiplied by
   var(--sc) and a reader can zoom, so both have to follow the size in use.

   The comment on each line is the size and leading pair the design is checked
   against. ui/test/type-scale.test.mjs holds them. */
:root {
  --fs-large-title:34px; --lh-large-title:1.2059; --tr-large-title:0.0118em;  /* 34/41 */
  --fs-title-1:28px;     --lh-title-1:1.2143;     --tr-title-1:0.0136em;      /* 28/34 */
  --fs-title-2:22px;     --lh-title-2:1.2727;     --tr-title-2:-0.0118em;     /* 22/28 */
  --fs-title-3:20px;     --lh-title-3:1.25;       --tr-title-3:-0.0225em;     /* 20/25 */
  --fs-headline:17px;    --lh-headline:1.2941;    --tr-headline:-0.0253em;    /* 17/22 */
  --fs-body:17px;        --lh-body:1.2941;        --tr-body:-0.0253em;        /* 17/22 */
  --fs-callout:16px;     --lh-callout:1.3125;     --tr-callout:-0.0194em;     /* 16/21 */
  --fs-subheadline:15px; --lh-subheadline:1.3333; --tr-subheadline:-0.0153em; /* 15/20 */
  --fs-footnote:13px;    --lh-footnote:1.3846;    --tr-footnote:-0.0062em;    /* 13/18 */
  --fs-caption-1:12px;   --lh-caption-1:1.3333;   --tr-caption-1:0;           /* 12/16 */
  --fs-caption-2:11px;   --lh-caption-2:1.1818;   --tr-caption-2:0.0055em;    /* 11/13 */

  --fw-headline:600;

  /* The system face. It picks the optical cut for the size it is drawn at.
     Naming a cut pins one and defeats that. Do not name one. */
  --font-ui: -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}

/* ── Type step ───────────────────────────────────────────────────────────────
   The same eleven styles at smaller sizes, for a denser layout. A page opts in
   with a class on <html>. A phone stays at the default step.

   Tracking is republished per step, not inherited. There is one absolute
   tracking per style, so the em that reproduces it at 17 does not at 15. */
html.type-small:not(.is-mobile) {
  --fs-large-title:32px; --lh-large-title:1.2188; --tr-large-title:0.0125em;  /* 32/39 */
  --fs-title-1:26px;     --lh-title-1:1.2308;     --tr-title-1:0.0146em;      /* 26/32 */
  --fs-title-2:20px;     --lh-title-2:1.2;        --tr-title-2:-0.013em;      /* 20/24 */
  --fs-title-3:18px;     --lh-title-3:1.2778;     --tr-title-3:-0.025em;      /* 18/23 */
  --fs-headline:15px;    --lh-headline:1.3333;    --tr-headline:-0.0287em;    /* 15/20 */
  --fs-body:15px;        --lh-body:1.3333;        --tr-body:-0.0287em;        /* 15/20 */
  --fs-callout:14px;     --lh-callout:1.3571;     --tr-callout:-0.0221em;     /* 14/19 */
  --fs-subheadline:13px; --lh-subheadline:1.3846; --tr-subheadline:-0.0177em; /* 13/18 */
  --fs-footnote:12px;    --lh-footnote:1.3333;    --tr-footnote:-0.0067em;    /* 12/16 */
  --fs-caption-1:11px;   --lh-caption-1:1.1818;   --tr-caption-1:0;           /* 11/13 */
  --fs-caption-2:11px;   --lh-caption-2:1.1818;   --tr-caption-2:0.0055em;    /* 11/13 */
}

/* ── Accessibility preferences ───────────────────────────────────────────────
   Both pages load this file, so a preference applies to both. Only rules that
   suit any page belong here. A selector naming dashboard elements, or an
   override of a token dashboard.css defines, stays in that file. */

/* Not zero. A duration of exactly 0 skips the transitionend event some code
   waits on. .01ms is instant and still fires. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* Reduced transparency: drop the blur, keep the motion. */
@media (prefers-reduced-transparency: reduce) {
  * { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
}

/* Increased contrast: raise the hues and every role follows. Both selectors are
   needed. The light theme sets the palette at a higher specificity, so a :root
   rule alone would leave the light hues unraised. */
@media (prefers-contrast: more) {
  :root, html[data-theme="light"] {
    --sy-red:var(--sy-red-hi);
    --sy-orange:var(--sy-orange-hi);
    --sy-yellow:var(--sy-yellow-hi);
    --sy-green:var(--sy-green-hi);
    --sy-mint:var(--sy-mint-hi);
    --sy-teal:var(--sy-teal-hi);
    --sy-cyan:var(--sy-cyan-hi);
    --sy-blue:var(--sy-blue-hi);
    --sy-indigo:var(--sy-indigo-hi);
    --sy-purple:var(--sy-purple-hi);
    --sy-pink:var(--sy-pink-hi);
    --sy-brown:var(--sy-brown-hi);
    --sy-gray:var(--sy-gray-hi);
    --sy-gray2:var(--sy-gray2-hi);
    --sy-gray3:var(--sy-gray3-hi);
    --sy-gray4:var(--sy-gray4-hi);
    --sy-gray5:var(--sy-gray5-hi);
    --sy-gray6:var(--sy-gray6-hi);
  }
}

/* ── Rules both pages need ───────────────────────────────────────────────── */

*, *::before, *::after { box-sizing:border-box; margin:0; padding:0 }

/* The wallpaper. Promoted to its own layer, so scrolling does not repaint
   it. */
html::before {
  content:''; position:fixed; inset:0; z-index:0;
  background-image:var(--bg-image,none);
  background-size:cover; background-position:center;
  pointer-events:none;
  filter:brightness(var(--bg-brightness,1));
  transform:translateZ(0);
}

/* Sits above the wallpaper. Each page adds its own sizing. */
body { background:transparent; position:relative; z-index:1 }
