/* ============================================================
   Fallowing Space — base.css
   Shared design tokens, reset, and common UI primitives.
   Aesthetic: warm, calm, professional. Not clinical.
   Loaded by index, controller, and display.
   ============================================================ */

:root {
  /* --- Surfaces & ink --- */
  /* NOT THE PAGE ANY MORE. The app alternated between two grounds — --sand
     for the page, --cream for every card on it, a step of ten points — and
     the ruling is ONE ground, the lighter of the two. --cream is the page
     now, and every card sits on it separated by the border and shadow the
     design guide already specified.

     --sand STAYS DECLARED, and is still painted, in two roles that are not
     the page: deliberate steps DOWN from a card (the EMDR track, the
     genogram ground, an inline code chip, the TO-DO status chip) and the
     three sticky bars that tint themselves with --sand-rgb at an alpha. It
     is wanted, not debris. */
  --sand:       #E9E9E7;   /* wells and insets; NOT the page — see above */
  --cream:      #F3F3F2;   /* THE GROUND, and raised surfaces / cards */
  /* Fields, buttons and tiles — eight points above --cream, and that
     relationship is unchanged: these already sat on --cream cards. Only
     the ones placed directly on the page moved, from eighteen points to
     eight, and every one of them carries a --line-strong border. */
  --cream-2:    #FBFBFA;   /* highest surface: fields, not ground */
  --ink:        #3A3B39;   /* primary text */
  --ink-soft:   #6A6B68;   /* secondary text */
  --ink-faint:  #9A9B97;   /* tertiary / hints */

  /* --- Brand & accents --- */
  --rust:       #B06E4F;   /* primary action */
  --rust-deep:  #955A3D;   /* pressed / hover */
  --rust-light: #F2C9B4;   /* orb highlight — the lit side of a rust sphere */
  --rust-tint:  #EADFD6;   /* soft rust fill */
  --clay:       #D5D5D1;   /* soft borders / fills */
  /* The arch of the mark, and nothing else yet. A step deeper than --clay
     because the mark is an OBJECT on a surface, not a border drawn on one:
     at --clay it sits too close to --cream to read as a shape at favicon
     size. Declared here rather than in the mark's own files so the mark
     cannot become the one place with a palette of its own. */
  --clay-deep:  #C6C4C0;   /* the mark's arch */
  /* THE CLIENT'S SKETCH PEN. Named for its ROLE, not its hue. Its job is to
     be unlike the therapist's pen — which is --rust — so that two people
     drawing on one shared surface can tell their marks apart. Deliberately
     NOT a brand colour: a rebrand that swept this along would take the
     distinction with it. sketch-pens.js is the only reader, and it reads
     this rather than holding a copy, because until it existed sketch.js and
     client.js held the pair TWICE and could diverge in silence. */
  --pen-client: #3F6FB0;

  --sage:       #8A9580;   /* calm secondary accent */
  --sage-deep:  #5C7048;   /* sage, pressed — as --rust-deep is to --rust */
  --sage-fill:  #7A8F6A;   /* base for TRANSLUCENT sage fills; --sage-tint is the solid one */
  --sage-tint:  #DEE4D9;

  /* --- Status (functional, fixed meanings) --- */
  --ok:    #4F7A4C;        /* green  — session healthy */
  --warn:  #D69B3C;        /* amber  — 10 min remaining */
  --alert: #C0392B;        /* red    — 5 min remaining */
  /* The green half of the status-chip pattern. The rust half has had
     --rust-deep + --rust-tint since the beginning; the green half was three
     literals in two rules because these two had no names. Deep text on a
     translucent fill, exactly as .row-docs.ready / .cd-status-sent do it. */
  --ok-deep: #46703A;      /* status-chip text */
  --ok-fill: #5F8A4F;      /* status-chip fill + border, used at alpha */

  /* Ink ON the dark scene surfaces. Not --cream-2: that is a light-mode
     surface, this is type over a near-black stage, and they must be free to
     move apart. */
  --on-dark: #FFFDF9;

  /* --- Channel triples, for the same colours used AT AN ALPHA ---
     rgba() cannot take a hex, so a translucent fill of a brand colour had to
     be written out by hand — and it rotted: six sites were still painted in
     the PREVIOUS rust (#BF5A2E) beside var(--rust-deep) in the same rule.
     These make the token drive the alpha instead.

     color-mix() would avoid the second token, but it is not byte-identical to
     rgba() across engines (premultiplication rounding) and nothing else in
     this codebase uses it. A triple is exact.

     EACH ONE MUST EQUAL ITS HEX. token-hygiene.test.js asserts that pair by
     pair — that test is the only thing standing between these and the same
     rot they were minted to end. */
  --ink-rgb:       58, 59, 57;
  --rust-rgb:      176, 110, 79;
  --sage-rgb:      138, 149, 128;
  --sage-fill-rgb: 122, 143, 106;
  --ok-fill-rgb:   95, 138, 79;
  --alert-rgb:     192, 57, 43;
  --sand-rgb:      233, 233, 231;
  --on-dark-rgb:   255, 253, 249;

  /* --- Lines & shadow --- */
  --line:       rgba(58, 59, 57, 0.10);
  --line-strong:rgba(58, 59, 57, 0.18);
  --shadow-sm:  0 1px 2px rgba(58, 59, 57, 0.05), 0 4px 12px rgba(58, 59, 57, 0.04);
  --shadow-md:  0 4px 16px rgba(58, 59, 57, 0.07);
  --shadow-lg:  0 14px 40px rgba(58, 59, 57, 0.09);

  /* --- Type ---
     --font-display is the READING face and --font-ui is the FIGURE face. They
     were the same family until v140, so any rule could ask for either and look
     right; they are different now and the choice is load-bearing. Figures —
     money, clocks, counters, anything in a column — take --font-ui. */
  --font-display: "Lora", Georgia, "Times New Roman", serif;
  --font-ui: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;
  /* THE SANS, NAMED, so a rule can ask for it against a display parent.
     .appt-offhours (controller.css) is a span inside .appt-when, which is
     --font-display; it asks for --font-sans to push itself back to sans. That
     token was never declared, so it resolved to `inherit` — which is the
     display face — and looked right only because both faces are the same sans
     today. The moment --font-display becomes a serif, that label inherits the
     SERIF, which is the exact opposite of what the rule is for, and no test
     would have caught it. Identical to --font-ui by definition: --font-ui is
     "the interface face", this is "specifically not the display face". */
  --font-sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;

  /* --- Geometry --- */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* --- Tap targets (tablet-first) --- */
  --tap: 60px;            /* minimum comfortable tap height */
  --tap-lg: 96px;         /* primary action height */

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font-ui);
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis: none;
  line-height: 1.45;
}

/* Warm atmospheric background for therapist-facing surfaces */
.warm-bg {
  background:
    radial-gradient(1200px 700px at 12% -10%, rgba(var(--rust-rgb), 0.06), transparent 60%),
    radial-gradient(900px 600px at 110% 10%, rgba(var(--sage-rgb), 0.07), transparent 55%),
    var(--cream);
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0;
}

button {
  font-family: var(--font-ui);
  cursor: pointer;
  border: none;
  background: none;
}

/* ---------- Card ---------- */
.card {
  background: var(--cream);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}

.card-title {
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  min-height: var(--tap);
  padding: 0 1.4rem;
  border-radius: var(--r-md);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--cream-2);
  border: 1px solid var(--line-strong);
  text-decoration: none;
  transition: transform 0.12s var(--ease), background 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(0.98); }
.btn.primary {
  background: var(--rust);
  color: #fff;
  border-color: var(--rust-deep);
  box-shadow: var(--shadow-md);
}
.btn.primary:active { background: var(--rust-deep); }

/* ---------- Licence lock screen ---------- */
.fs-lock {
  position: fixed; inset: 0; z-index: 9999;
  background: var(--cream);
  display: flex; align-items: center; justify-content: center;
  padding: 1.4rem;
}
.fs-lock-card {
  width: 100%; max-width: 420px; text-align: center;
  background: var(--cream-2); border: 1px solid var(--line);
  border-radius: var(--r-lg, 18px); padding: 2rem 1.6rem;
  box-shadow: var(--shadow-md);
}
.fs-lock-logo { font-family: var(--font-display, Georgia, serif); font-size: 1.8rem; font-weight: 600; margin-bottom: 0.8rem; }
.fs-lock-logo .a { color: var(--rust); }
.fs-lock-msg { color: var(--ink-soft); margin: 0 0 1rem; line-height: 1.45; }
.fs-key {
  width: 100%; resize: vertical; font-family: monospace; font-size: 0.9rem;
  padding: 0.7rem 0.8rem; border: 1px solid var(--line-strong);
  border-radius: var(--r-md, 12px); background: #fff; margin-bottom: 0.6rem;
}
.fs-err { color: var(--alert); font-size: 0.85rem; min-height: 1.1rem; margin-bottom: 0.4rem; }
.fs-lock-card .btn { width: 100%; min-height: var(--tap, 48px); }
.fs-fine { color: var(--ink-faint); font-size: 0.78rem; margin: 1rem 0 0; line-height: 1.4; }
/* The one warning a therapist must not skim: forget this passphrase and the
   records are gone. .fs-err is the live error line under a field — 0.85rem and
   transient — so it cannot carry this. Full size, boxed, left-aligned so the
   list reads as terms rather than decoration, in --alert because this is the
   token that already means "consequence". */
.fs-warn {
  color: var(--alert); font-weight: 600; text-align: left; line-height: 1.45;
  border: 1px solid var(--alert); border-radius: var(--r-md, 12px);
  padding: 0.9rem 1rem; margin: 0 0 1rem;
}
.fs-warn ul { margin: 0.5rem 0 0; padding-left: 1.15rem; font-weight: 500; }
.fs-warn li { margin: 0.3rem 0; }

/* Lapsed-licence banner. Not a lock: it sits at the top of the page, says what
   is paused and what still works, and leaves everything readable beneath it.
   The full-screen .fs-lock above is now only the key-entry form, opened on
   request and dismissible. */
.fs-lapsed {
  position: sticky; top: 0; z-index: 900;
  display: flex; align-items: center; justify-content: center; gap: 0.9rem; flex-wrap: wrap;
  padding: 0.7rem 1rem;
  background: var(--rust-tint); color: var(--rust-deep);
  border-bottom: 1px solid var(--clay);
  font-size: 0.9rem; line-height: 1.45;
}
.fs-lapsed-txt { flex: 1 1 20rem; min-width: 0; }
.fs-lapsed .btn { flex: 0 0 auto; min-height: 40px; }

/* Keyboard focus ring (accessibility) */
:focus-visible { outline: 2px solid var(--rust); outline-offset: 2px; border-radius: 4px; }

/* The HTML hidden attribute, made to work.
   Its effect comes from the user agent's [hidden] { display: none }, and ANY
   author display declaration outranks a user-agent one whatever the
   specificity — so .btn above (display: inline-flex) silently defeated hidden
   on every button in the app. This restores it globally.
   !important is load-bearing, not decoration: [hidden] and .btn have equal
   specificity, so without it this rule wins only by sitting later in the file,
   and any future reordering would break it again. */
[hidden] { display: none !important; }
