/* ============================================================
   TOKENS — the single source of truth for colour, type and space.
   Mirrored verbatim into the Claude Design project, so the design
   system and the running app cannot drift apart.

   Palette brief: this is read on a phone in a hallway AND on a screen
   bolted to a laundry-room wall, from about three metres, often under
   a single fluorescent tube. So:

     - contrast first, decoration never
     - state is NEVER carried by hue alone. Free vs taken differs in
       fill, in weight, and in the word printed on it, so the screen
       still works for a colourblind resident, in glare, or at an angle
     - a warm neutral rather than pure grey, because pure grey under
       fluorescent light reads slightly blue and slightly clinical
   ============================================================ */

:root {
  /* --- Neutral ink scale ------------------------------------- */
  --ink-0:   #ffffff;
  --ink-50:  #f8f8f7;
  --ink-100: #efefed;
  --ink-200: #dededb;
  --ink-300: #c3c2be;
  --ink-400: #999893;
  --ink-500: #74736e;
  --ink-600: #565551;
  --ink-700: #3c3b38;
  --ink-800: #262523;
  --ink-900: #121211;

  /* --- Surfaces ---------------------------------------------- */
  --bg-app:      var(--ink-50);
  --surface:     var(--ink-0);
  --surface-sunk: var(--ink-100);
  --surface-hover: var(--ink-50);
  --surface-press: var(--ink-100);

  /* The inverse pair: a toast sits on top of everything, so it is the
     page turned inside out. Flips with the theme — a near-black toast on
     a near-black page has no edge. */
  --inverse-surface: var(--ink-900);
  --inverse-text:    var(--ink-0);
  /* An address as a plate: enamel, like the sign on a door. Its own pair,
     not the inverse surface borrowed, so a plate can change alone. */
  --plate-ground: var(--ink-900);
  --plate-ink:  var(--ink-0);

  /* What a dialog dims the page with. */
  --scrim:        rgb(0 0 0 / 0.4);
  --scrim-strong: rgb(0 0 0 / 0.55);

  /* --- Text --------------------------------------------------- */
  --text-strong: var(--ink-900);
  --text-body:   var(--ink-800);
  --text-muted:  var(--ink-500);
  --text-faint:  var(--ink-400);

  /* --- Lines -------------------------------------------------- */
  --line:        var(--ink-200);
  --line-strong: var(--ink-300);

  /* --- Slot states -------------------------------------------
     Each has a fill, a border and a text colour. The text colour passes
     AA on its own fill and on --surface, in both themes — the test
     measures every pairing. Nowhere else. */
  --free-fill:   #e7f2e5;
  --free-line:   #6fa06a;
  --free-text:   #1f5c22;

  --mine-fill:   #e3edf8;
  --mine-line:   #3b7cc4;
  --mine-text:   #14528f;

  --closed-fill: #faf0d9;
  --closed-line: #c9a44a;
  --closed-text: #7a4f05;

  --danger-fill: #fbeaea;
  --danger-line: #d08b8b;
  --danger-text: #92292a;
  /* A wrong box's edge: 3:1 on --surface, where --danger-line is a tint's
     border and too faint to tell a wrong box from a resting one. */
  --danger-edge: #c76666;
  /* A box that warns (allowed, think twice): its edge at 3:1 on --surface
     too, where --attention-line is a tint's border. */
  --attention-edge: #a8822a;

  /* --- States that are not about a slot -----------------------
     "Added", "Done", a field that checks out; a row that needs somebody.
     They start as the calendar's greens and ambers and are named apart
     on purpose: a free slot and a finished step are different facts, and
     one can change without the other. Each is a fill, a line and a text
     colour, measured by the same test, and is always drawn with its
     icon (a tick, an alert). They follow the theme through the tokens
     they point at. */
  --ok-fill:   var(--free-fill);
  --ok-line:   var(--free-line);
  --ok-text:   var(--free-text);

  --attention-fill: var(--closed-fill);
  --attention-line: var(--closed-line);
  --attention-text: var(--closed-text);

  /* Taken slots are deliberately NEUTRAL, not a colour. They are the
     most common state on a busy calendar, and colouring them would
     turn the whole screen into noise and leave "free" competing for
     attention instead of owning it. */
  --taken-fill:  var(--ink-100);
  --taken-line:  var(--ink-300);
  --taken-text:  var(--ink-800);
  /* How far a taken tile in a week steps back. The test holds the word on
     it to AA after the fade, in both themes. */
  --taken-fade:  0.7;

  --accent:      #1d5fa8;
  --accent-hover:#164a83;
  /* What is chosen, as a ground: the step you are on, a day that is on.
     The solid accent is for the one thing to do; a row of solid toggles
     is a third of the screen shouting. */
  --accent-tint: var(--mine-fill);
  /* Text ON a solid fill is its own token, because the fill changes
     lightness between themes and the text has to change with it. */
  --on-accent:   var(--ink-0);

  --danger-solid: #92292a;
  --on-danger:    var(--ink-0);

  /* A space's face: one of seven colours, chosen by the board in Admin ->
     Spaces, else its kind's (functions/api/_colours.js; STYLE.md, "Colour").
     The solid is the chosen tab and the space card's head, under white
     words; the tint is a tab at rest, under the ink. Never a state, never a
     button. No red, amber, green or the accent blue: those already mean
     refused, needs somebody, free and yours, right beside the cards. Bark is
     a dark, low brown, well away from the refused red. */
  --on-kind:            var(--ink-0);
  --space-teal-solid:      #0b5c58;
  --space-teal-tint:       #ddf1ef;
  --space-teal-ink:        #0b5c58;
  --space-plum-solid:      #8a2160;
  --space-plum-tint:       #f8e3ef;
  --space-plum-ink:        #8a2160;
  --space-indigo-solid:    #463a9e;
  --space-indigo-tint:     #ebe8f8;
  --space-indigo-ink:      #463a9e;
  --space-purple-solid:    #6a2f86;
  --space-purple-tint:     #f1e5f6;
  --space-purple-ink:      #6a2f86;
  --space-graphite-solid:  var(--ink-700);
  --space-graphite-tint:   var(--ink-100);
  --space-graphite-ink:    var(--ink-700);
  --space-olive-solid:     #4f5e1e;
  --space-olive-tint:      #eff0d6;
  --space-olive-ink:       #4f5e1e;
  --space-bark-solid:      #6e4529;
  --space-bark-tint:       #f3e8df;
  --space-bark-ink:        #6e4529;

  /* --- Type ---------------------------------------------------
     System stack: fastest first paint on a Raspberry Pi, no licence
     to track, and no layout shift while a webfont loads on a screen
     nobody is going to reload. */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --text-xs:  0.75rem;   /* 12px — labels, metadata */
  --text-sm:  0.875rem;  /* 14px — secondary */
  --text-md:  1rem;      /* 16px — body, and the phone minimum that avoids iOS zoom-on-focus */
  --text-lg:  1.125rem;  /* 18px */
  --text-xl:  1.375rem;  /* 22px — section headings */
  --text-2xl: 1.75rem;   /* 28px */

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-bold:    600;

  --lh-tight:  1.15;
  --lh-snug:   1.3;
  --lh-normal: 1.5;

  /* Large type is drawn for reading at small sizes and looks loose when
     it is scaled up, so headings close up a little. Body text is left
     alone. */
  --tracking-tight: -0.02em;
  /* A one-time code is read and typed a digit at a time. */
  --tracking-code: 0.35em;

  /* --- Display type ---------------------------------------------
     For dates and the period title, and nothing else: the
     numeral is the thing people look for, so it gets a face and a weight
     the body text does not. Body stays on the system stack. The wall
     screen sets its own (kiosk.css). A face that has not loaded falls
     back to the system stack, so nothing waits on it. */
  --font-display: "Schibsted Grotesk", var(--font-sans);
  --fw-heavy: 800;
  --text-3xl: 2.25rem;   /* 36px — a date on the wall screen; the period title there */

  --icon-sm: 16px;  /* beside small text: a state word, a field's message */
  --icon-md: 20px;
  --icon-lg: 24px;
  /* A space's own mark: on its tab, and the building's beside its name. */
  --icon-xl: 32px;
  /* The mark on a space card's coloured head. */
  --icon-2xl: 48px;

  /* --- Space --------------------------------------------------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;

  --radius-sm: 6px;
  /* 8px controls inside 12px cards: the corner family of current product
     software (Linear, Cal.com), one step crisper than it was. */
  --radius:    8px;
  --radius-lg: 12px;
  --radius-pill: 999px; /* a switch's track, and a person's disc: the two fully round shapes */
  /* A date's mark and an apartment's plate. Square-shouldered, like the
     enamel number on a door; the wall screen squares them off entirely. */
  --radius-mark:  5px;
  --radius-plate: 4px;

  /* Touch targets. 44px is the accessibility floor for a phone; the
     wall screen gets more, because people jab at it with a laundry
     basket under one arm. */
  --touch-min:   44px;
  --touch-kiosk: 64px;

  /* Focus is an outline, not a shadow: shadows are how emphasis is drawn
     (see .ssb-cell--mine), and a focus shadow would erase it. It is the
     strongest ink, not the accent: an accent ring on a chosen (accent or
     kind-coloured) control disappeared. --ring-gap is how far out it sits;
     a control inside a box that clips sets it below zero (base.css). */
  --ring-color: var(--text-strong);
  --ring-width: 3px;
  --ring-gap:   2px;

  --shadow-raised: 0 1px 2px rgb(0 0 0 / 0.08);
  /* What hangs over the page: the account menu at a desk. */
  --shadow-overlay: 0 12px 28px rgb(0 0 0 / 0.14);

  /* --- Marking a date -------------------------------------------
     Today and the day being viewed are drawn the same way wherever a date
     is drawn: the date block, the month grid, the wall week. These are the
     one place that is decided. Today is an accent plate with an accent
     rim; the day being viewed is an accent ring with no fill,
     so the two still differ by fill and not by hue. They are never both
     (when the day being viewed is today, only today's mark is drawn).
     Emphasis is an inset shadow, so a marked date is the size of its
     neighbours. */
  --today-bg:      var(--accent);
  --today-ink:     var(--on-accent);
  --today-shadow:  inset 0 0 0 3px var(--accent), inset 0 0 0 4px var(--bg-app);
  --selected-bg:     transparent;
  --selected-ink:    var(--text-strong);
  --selected-shadow: inset 0 0 0 2px var(--accent);

  /* --- Layers --------------------------------------------------
     Everything that floats above the page, in the order it stacks.
     A toast outranks a sheet because it reports on what the sheet just
     did; the skip link outranks everything because it is the way out. */
  --z-panel: 40;
  --z-sheet: 50;
  --z-toast: 60;
  --z-skip:  100;

  /* --- Motion ---------------------------------------------------
     Crisp and short. This is a tool people use with a basket under one
     arm, several times a week, so almost nothing moves, and what does
     is over before it is noticed.

       press   the control acknowledging a finger
       fast    hover and colour changes
       base    a dialog or toast arriving
       exit    anything leaving — always quicker than it arrived
       sheet   the phone bottom sheet, the one long movement

     Curves: things entering or leaving use --ease-out (fast start, so
     the response is immediate). Things moving on screen use
     --ease-in-out. Colour uses --ease. There is deliberately no
     ease-in: it delays the moment the user is watching. */
  --dur-press: 140ms;
  --dur-fast:  120ms;
  --dur-base:  200ms;
  --dur-exit:  150ms;
  --dur-sheet: 300ms;

  --ease:        ease;
  --ease-out:    cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

  /* A press letting go: Motion's spring, sampled (scripts/spring-curve.mjs
     writes these two lines). It runs past where it started by a hair and
     lands. Only for something a finger let go of; a drag released is
     spring.js's, at the finger's own speed. */
  --dur-spring:  300ms;
  --ease-spring: linear(0, 0.124, 0.383, 0.653, 0.868, 1.007, 1.076, 1.095, 1.083, 1.058, 1.033, 1.012, 0.999, 0.993, 0.991, 0.992, 0.994, 0.997, 0.999, 1, 1);

  --press-scale: 0.97;

  /* --- People in a household ----------------------------------
     A person is a round initial in one of five tints, taken in the order
     they joined the household, so two people of one apartment never share
     one. Recognition, not state: never on the wall screen, and never the
     only thing that says who somebody is (the name is always beside it).
     Ink on fill passes AA in both themes (tests/design-system.test.mjs). */
  --person-1-fill: #f6dde3;  --person-1-text: #8a2541;   /* rose  */
  --person-2-fill: #e4ead2;  --person-2-text: #46561a;   /* olive */
  --person-3-fill: #efe2d6;  --person-3-text: #6b4026;   /* cocoa */
  --person-4-fill: #dde3ea;  --person-4-text: #33475e;   /* slate */
  --person-5-fill: var(--ink-100); --person-5-text: var(--ink-700);
  /* A choice that was tapped is played pressing in after the finger has
     gone (the Day / Week / Month switch): deeper than a held press, so a
     tap that took a tenth of a second is still seen. */
  --press-in-scale: 0.94;

  /* --- The brand, and the building's header -----------------------
     The Maretou mark is a picture, not a theme: its colours are the same
     in both themes and are written once, here (design/brand/maretou-mark.svg,
     Ivan's choice of 2026-10-20). The header is the building's photo, or
     the brand's blue when there is none, with its two top corners cut out
     for the mark and the account: an even gap, and the photo turning in
     one curve where it meets each cut. */
  --brand-blue:   #1d5fa8;
  --brand-navy:   #0c3a6b;
  --brand-amber:  #f2a33a;
  --brand-window: #d6e6f7;
  --brand-white:  #ffffff;
  --tracking-brand: 0.16em;

  /* 72px on a phone; at a desk no more than 88px, so the calendar still
     starts on the first screen of a 1024x768 laptop. */
  --hero-mark:   clamp(72px, 1.5vw + 56px, 88px);
  --hero-mark:   round(clamp(72px, 1.5vw + 56px, 88px), 2px);
  /* Whole pixels: a cut-out edge at half a pixel over a photo shows a seam.
     Each value is given twice: a browser without round() (Chrome before 125,
     Safari before 15.4) keeps the first instead of losing both. */
  --hero-gap:    12px;
  --hero-gap:    round(clamp(12px, 0.3vw + 11px, 14px), 1px);
  --hero-height: clamp(168px, 12vw + 124px, 248px);
  --radius-hero: 20px;
  --radius-hero-mark: calc(var(--hero-mark) * 0.27);
  --radius-hero-mark: round(calc(var(--hero-mark) * 0.27), 1px);
  --radius-hero-cut: calc(var(--radius-hero-mark) + var(--hero-gap));
  /* The building's name: 32px on a phone, 60px on a wide screen. */
  --text-hero: clamp(2rem, 1.3rem + 3vw, 3.75rem);
  --text-hero-apartment: clamp(1.375rem, 1vw + 1.125rem, 1.875rem);
  --lh-hero: 1;
  --tracking-hero: -0.035em;
  /* The photo darkens towards its foot, so white words read on any photo. */
  --hero-shade: linear-gradient(to top, rgb(8 30 56 / 0.9), rgb(8 30 56 / 0.45) 50%, rgb(8 30 56 / 0) 80%);
  --hero-plain: linear-gradient(135deg, var(--brand-navy), var(--brand-blue));
  --hero-text-shadow: 0 2px 18px rgb(4 18 36 / 0.55);
}

/* ============================================================
   Dark theme. The wall screen lives in a basement corridor that is
   dim at night, and a full-brightness white panel there is genuinely
   unpleasant. Follows the system by default; the kiosk can pin it.
   ============================================================ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg-app:        var(--ink-900);
    --surface:       #1b1a19;
    --surface-sunk:  #121211;
    --surface-hover: #262523;
    --surface-press: #302f2c;
    --inverse-surface: var(--ink-100);
    --inverse-text:    var(--ink-900);
    --plate-ground: var(--ink-100);
    --plate-ink:  var(--ink-900);

    --text-strong: var(--ink-0);
    --text-body:   var(--ink-100);
    --text-muted:  var(--ink-400);
    --text-faint:  var(--ink-500);

    --line:        #34332f;
    --line-strong: #4a4844;

    --free-fill:   #1c2e1c;
    --free-line:   #4a7a45;
    --free-text:   #a8d7a2;

    --mine-fill:   #16283d;
    --mine-line:   #3b7cc4;
    --mine-text:   #a9cdf2;

    --closed-fill: #33280f;
    --closed-line: #8a6f2a;
    --closed-text: #e6c878;

    --danger-fill: #351a1a;
    --danger-line: #8a4444;
    --danger-text: #efaaaa;
    --danger-edge: #ad5959;
    --attention-edge: #8a6f2a;

    --taken-fill:  #262523;
    --taken-line:  #4a4844;
    --taken-text:  var(--ink-100);

    --accent:      #6ea8e0;
    --accent-hover:#8dbdea;
    --on-accent:   var(--ink-900);
    --danger-solid: #efaaaa;
    --on-danger:    var(--ink-900);
    --space-teal-solid:      #1d6b65;
    --space-teal-tint:       #12302e;
    --space-teal-ink:        #8fd6cf;
    --space-plum-solid:      #8f3367;
    --space-plum-tint:       #3a1830;
    --space-plum-ink:        #f0a8d8;
    --space-indigo-solid:    #5145a8;
    --space-indigo-tint:     #24213f;
    --space-indigo-ink:      #bdb6f6;
    --space-purple-solid:    #74408f;
    --space-purple-tint:     #301f3b;
    --space-purple-ink:      #dcb0ee;
    --space-graphite-solid:  #4a4844;
    --space-graphite-tint:   var(--ink-800);
    --space-graphite-ink:    var(--ink-200);
    --space-olive-solid:     #5b6b25;
    --space-olive-tint:      #2b2f14;
    --space-olive-ink:       #d3dc9a;
    --space-bark-solid:      #7a5034;
    --space-bark-tint:       #33241a;
    --space-bark-ink:        #e8c4a6;
    --shadow-raised: 0 1px 2px rgb(0 0 0 / 0.4);
    --person-1-fill: #3d2129;  --person-1-text: #f2bccb;
    --person-2-fill: #2b321b;  --person-2-text: #cfdca6;
    --person-3-fill: #35281e;  --person-3-text: #e8cbb2;
    --person-4-fill: #222c37;  --person-4-text: #bfd2e8;
    --person-5-fill: var(--ink-800); --person-5-text: var(--ink-200);
    --shadow-overlay: 0 12px 28px rgb(0 0 0 / 0.5);
  }
}

/* Explicit override, so the kiosk can pin a theme regardless of what
   the Raspberry Pi's OS thinks the time of day is. */
:root[data-theme="dark"] {
  --bg-app:        var(--ink-900);
  --surface:       #1b1a19;
  --surface-sunk:  #121211;
  --surface-hover: #262523;
  --surface-press: #302f2c;
  --inverse-surface: var(--ink-100);
  --inverse-text:    var(--ink-900);
  --plate-ground: var(--ink-100);
  --plate-ink:  var(--ink-900);
  --text-strong: var(--ink-0);
  --text-body:   var(--ink-100);
  --text-muted:  var(--ink-400);
  --text-faint:  var(--ink-500);
  --line:        #34332f;
  --line-strong: #4a4844;
  --free-fill:   #1c2e1c;
  --free-line:   #4a7a45;
  --free-text:   #a8d7a2;
  --mine-fill:   #16283d;
  --mine-line:   #3b7cc4;
  --mine-text:   #a9cdf2;
  --closed-fill: #33280f;
  --closed-line: #8a6f2a;
  --closed-text: #e6c878;
  --danger-fill: #351a1a;
  --danger-line: #8a4444;
  --danger-text: #efaaaa;
  --danger-edge: #ad5959;
  --attention-edge: #8a6f2a;
  --taken-fill:  #262523;
  --taken-line:  #4a4844;
  --taken-text:  var(--ink-100);
  --accent:      #6ea8e0;
  --accent-hover:#8dbdea;
  --on-accent:   var(--ink-900);
  --danger-solid: #efaaaa;
  --on-danger:    var(--ink-900);
  --space-teal-solid:      #1d6b65;
  --space-teal-tint:       #12302e;
  --space-teal-ink:        #8fd6cf;
  --space-plum-solid:      #8f3367;
  --space-plum-tint:       #3a1830;
  --space-plum-ink:        #f0a8d8;
  --space-indigo-solid:    #5145a8;
  --space-indigo-tint:     #24213f;
  --space-indigo-ink:      #bdb6f6;
  --space-purple-solid:    #74408f;
  --space-purple-tint:     #301f3b;
  --space-purple-ink:      #dcb0ee;
  --space-graphite-solid:  #4a4844;
  --space-graphite-tint:   var(--ink-800);
  --space-graphite-ink:    var(--ink-200);
  --space-olive-solid:     #5b6b25;
  --space-olive-tint:      #2b2f14;
  --space-olive-ink:       #d3dc9a;
  --space-bark-solid:      #7a5034;
  --space-bark-tint:       #33241a;
  --space-bark-ink:        #e8c4a6;
  --shadow-raised: 0 1px 2px rgb(0 0 0 / 0.4);
  --person-1-fill: #3d2129;  --person-1-text: #f2bccb;
  --person-2-fill: #2b321b;  --person-2-text: #cfdca6;
  --person-3-fill: #35281e;  --person-3-text: #e8cbb2;
  --person-4-fill: #222c37;  --person-4-text: #bfd2e8;
  --person-5-fill: var(--ink-800); --person-5-text: var(--ink-200);
  --shadow-overlay: 0 12px 28px rgb(0 0 0 / 0.5);
}
