/* Colours, both themes, the text scale and the motion setting. Every
   other file in here reads these and defines none of its own. */

:root{
  /* Warmed to sit with the mascot's burnt-amber shell and near-black outline */
  --bg:#F4F1EA;
  --panel:#FFFDF9;
  --ink:#1E1710;
  --ink-soft:#6B6055;
  --line:#E3DCD0;
  --amber:#E9A23B;
  --amber-deep:#96601F;
  --shell:#C98D3E;
  --outline:#1A1206;
  --blue:#2D6CB8;
  --blue-deep:#1F4E88;
  --coral:#E8543E;
  --locked:#CFC7B9;
  --locked-bg:#E8E2D7;
  --teal:#1E8A82;
  --sim-bg:#0F1224;
  --tint:#E8EFF8;
  --mascot-stroke:#1A1206;
  --on-accent:#FFFFFF;
  --on-ink:#FFFFFF;
  --tint-warm:#FFF9EE;
  --tint-warn:#FDECEA;
  --surface-2:#FAF7F1;
  --amber-text:#8A5A0A;
      /* amber-deep fails on cream at small sizes */
  --coral-text:#B03A26;
  --teal-text:#0F6B65;
  --tint-cool:#E6F4EF;
  --go:#4CC49E;  --on-go:#0B2B23;
  --on-amber:#14120E;
  /* Resistor colour bands. The one place a colour carries meaning rather
     than styling, so these are identical in both themes — a yellow band is
     yellow on a real part whatever the phone is set to. Every banded
     resistor also prints the colour names, because colour alone is not
     readable by everyone and naming them is the skill 6.1 teaches. */
  --band-black:#141210;  --band-brown:#6B4525;  --band-red:#C62A1E;
  --band-orange:#E2701A; --band-yellow:#EFC53F; --band-green:#2E8B4A;
  --band-blue:#2D6CB8;   --band-violet:#7B4CA8; --band-grey:#8C8880;
  --band-white:#F7F5F0;  --band-gold:#C9992E;   --band-silver:#B9B7B2;

  /* Motion: the easing and the three durations every animation uses. The
     animations themselves are in motion.css — these are here because there
     is exactly one :root in this app, and contrast.test.js depends on that.
     Quick away, soft arrival; nothing decelerates long enough to be admired. */
  /* The ink behind a modal and under a raised card. Given as channels
     rather than a colour because it is always used with an alpha, and
     deliberately not themed: a scrim is dark on a dark page too, and
     four files had this same triple typed into them by hand. */
  --scrim-ink:20,23,43;

  --ease-out:cubic-bezier(.2,.7,.3,1);
  --t-quick:160ms;
  --t-base:200ms;
  --t-screen:240ms;
}

/* Dark theme. The mascot's outline is near-black, so it gets a light
   variant here or it disappears entirely against the background. */
html[data-theme="dark"]{
  --bg:#14120E;
  --panel:#1C1A15;
  --ink:#F0EAE0;
  --ink-soft:#A79E90;
  --line:#332F27;
  --amber:#F2B455;
  --amber-deep:#E09A38;
  --shell:#C98D3E;
  --outline:#0C0906;
  --blue:#6AA3E8;
  --blue-deep:#8FBBF0;
  --coral:#F2755F;
  --locked:#4A453B;
  --locked-bg:#2A2721;
  --teal:#3FB3A8;
  --sim-bg:#0A0908;
  --tint:#22303F;
  --mascot-stroke:#E8DFD0;
  --tint-warm:#2B2317;
  --tint-warn:#3A2019;
  --surface-2:#232019;      /* was a hardcoded cream that never flipped */
  --amber-text:#F2B455;
  --coral-text:#F2755F;
  --teal-text:#4FC4B8;
  --tint-cool:#16302B;
  --go:#4CC49E;  --on-go:#0B2B23;   /* light in both themes -> dark text */
  --on-amber:#14120E;       /* amber is light in both themes -> dark text */
  --on-accent:#14120E;      /* accents are light in dark mode -> dark text */
  --on-ink:#14120E;         /* --ink is near-white in dark mode */
}

/* Text scale. Rules across the app use fixed px, so setting a root
   font-size achieves nothing; the container is scaled instead.

   The factor is a variable because #app's min-height has to divide by it.
   zoom scales the painted box without changing what 100vh resolves to, so a
   container asked for 100vh at zoom 1.15 is painted 115vh tall and the page
   grows a scrollbar with nothing under it — which got worse the larger the
   text was set. Four hand-written divisions would be four chances to forget
   one. */
html[data-size="s"] { --zoom:0.9;  }
html[data-size="m"] { --zoom:1;    }
html[data-size="l"] { --zoom:1.15; }
html[data-size="xl"]{ --zoom:1.3;  }
#app{ zoom:var(--zoom,1); }
@supports not (zoom:1){
  /* transform does not change the layout box, so the same divided height is
     already the right one to scale up from.

     Listed size by size rather than written once against #app, because a
     transform — scale(1) included — makes the element a containing block for
     every position:fixed descendant. Applied unconditionally it would move
     all five overlays from the window to #app at the DEFAULT text size, which
     is the bug that has already cost five separate 'the button is off-screen'
     reports. This way nothing changes unless the text was actually scaled. */
  html[data-size="s"]  #app,
  html[data-size="l"]  #app,
  html[data-size="xl"] #app{ transform:scale(var(--zoom,1)); transform-origin:top center; }
}

html[data-motion="reduced"] *{ transition:none !important; animation:none !important; }

/* Device safe areas (status bar, punch-hole, gesture bar). 0 on desktop.
   These live here rather than next to the reset that used to follow them,
   because :root belongs in one file: contrast.test.js resolves variables by
   collecting every :root rule in source order, and a second declaration
   somewhere else would still work in the browser while quietly changing what
   that suite is measuring. */
/* Device safe areas (status bar, punch-hole, gesture bar). 0 on desktop. */
/* Two sources, in the order that works.

   env(safe-area-inset-*) is the standard and is what iOS answers. Android's
   WebView does not reliably fill it in, which is why Capacitor 8 injects
   --safe-area-inset-* as real custom properties from the native side — read
   off the window insets, in CSS pixels, updated when the bars change.

   API 36 makes edge-to-edge non-optional: an app can no longer ask the system
   to leave room for the status bar. So on the target we are now obliged to
   build against, reading only env() would give 0 on Android and put the top
   bar underneath the clock. The var() is tried first and env() is the
   fallback, which is also what a browser gets — there is no Capacitor there
   and nothing sets the custom property. */
:root{--sat:var(--safe-area-inset-top,env(safe-area-inset-top,0px));
  --sab:var(--safe-area-inset-bottom,env(safe-area-inset-bottom,0px));
  --sal:var(--safe-area-inset-left,env(safe-area-inset-left,0px));
  --sar:var(--safe-area-inset-right,env(safe-area-inset-right,0px));}

/* How much room the page leaves around #app. 0 on a phone, where the app is
   the whole window; base.css widens it above 520px. */
:root{--shell-gap:0px;}
