/* Revive Partners: design tokens.
 *
 * Ported from the house design language (the portal's static/tokens.css, itself ported from
 * the brain's scripts/dashboard_css.py) so this site and the portal are recognisably one
 * system. Colour values are decided in revive/brain/brand/README.md, which is the authority:
 * if a value here disagrees with that note, that note wins.
 *
 * Page styles consume these tokens and carry no literal colour, which is what makes a re-skin
 * cost one file.
 *
 * Typeface note, and it is binding: IBM Plex Sans is the interface face. Sora belongs to the
 * logo only, and the logo files are outlines, so no page ever loads Sora.
 */

@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("fonts/IBMPlexSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  src: url("fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
}

:root {
  color-scheme: light dark;

  /* Ground and ink */
  --canvas: #fafafa;
  --canvas-soft: #f1f1f2;
  --ink: #131316;
  --body: #4b4b52;
  --muted: #67676e;
  --hairline: #e2e2e5;

  /* Brand accent */
  --accent: #274b9f;
  --accent-strong: #1e3a7d;
  --accent-wash: rgba(39, 75, 159, 0.10);
  --on-accent: #ffffff;

  /* Form controls.
     A text field here has no fill of its own, so its BORDER is the only thing marking where to
     type, and WCAG 1.4.11 puts a 3:1 floor on a boundary that identifies a control.
     --field-edge is 1.70:1 on canvas and 1.60:1 in dark, so it must never be a field's only
     boundary. It is kept because the ported house tokens define it, and used only where some
     other cue identifies the control. Resting field borders use --control-edge (3.75:1 light,
     3.53:1 dark) and hover uses --body. */
  --field-edge: #c2c2ca;
  --control-edge: #808088;
  --placeholder: #696971;
  --danger-text: #8a2b2b;
  --danger-wash: rgba(198, 69, 69, 0.16);
  --success-text: #026b3f;
  --success-wash: rgba(20, 158, 97, 0.16);

  /* Type. Display ceiling is 6rem per the craft floor; tracking never below -0.04em. */
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --step--1: clamp(0.83rem, 0.80rem + 0.15vw, 0.89rem);
  --step-0: clamp(1.00rem, 0.96rem + 0.22vw, 1.13rem);
  --step-1: clamp(1.20rem, 1.12rem + 0.40vw, 1.42rem);
  --step-2: clamp(1.44rem, 1.30rem + 0.70vw, 1.80rem);
  --step-3: clamp(1.73rem, 1.49rem + 1.18vw, 2.27rem);
  --step-4: clamp(2.07rem, 1.66rem + 2.05vw, 3.10rem);
  --step-5: clamp(1.90rem, 1.45rem + 2.10vw, 3.00rem);
  /* The shared page column. Deliberately NOT in `ch`: that unit resolves against each
     element's own font-size, so a footer set one step smaller got a narrower column from the
     same token and stopped lining up with the content above it. A rem is the same width
     everywhere it is used. 40rem lands rendered body lines around 74 characters at 1280. */
  --column: 40rem;
  /* Prose line length, for a block that needs capping independently of the page column. */
  --measure: 58ch;
  --leading-tight: 1.12;
  --leading-body: 1.6;
  --tracking-display: -0.025em;

  /* Space. One scale, used everywhere, so rhythm is a decision and not an accident. */
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-s: 0.75rem;
  --space-m: 1.25rem;
  --space-l: 2rem;
  --space-xl: 3.25rem;
  --space-2xl: 5.25rem;
  --space-3xl: 8.5rem;

  --radius-control: 10px;
  --radius-card: 16px;

  /* Depth. Offset plus soft blur, never a zero-offset halo. */
  --shadow-subtle: rgba(0, 0, 0, 0.03) 0 4px 24px;
  --shadow-hover: rgba(0, 0, 0, 0.09) 0 10px 32px;

  /* Motion. Exponential ease-out from an already-visible default. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 140ms;
  --dur-base: 260ms;
  --dur-slow: 620ms;
}

/* Dark is chosen from the use scene, not from category habit: a clinical director reads this
   on a phone, often on a ward at night. Follow the system rather than imposing either. */
@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #161618;
    --canvas-soft: #1e1e21;
    --ink: #ececea;
    --body: #b9b9c0;
    --muted: #8b8b92;
    --hairline: #2c2c31;

    --accent: #8fa9ff;
    --accent-strong: #aabcff;
    --accent-wash: rgba(143, 169, 255, 0.14);
    --on-accent: #131316;

    --field-edge: #3a3a41;
    --control-edge: #6d6d77;
    --placeholder: #8b8b92;
    --danger-text: #f0a3a3;
    --danger-wash: rgba(198, 69, 69, 0.22);
    --success-text: #7fd9b0;
    --success-wash: rgba(20, 158, 97, 0.22);

    --shadow-subtle: rgba(0, 0, 0, 0.30) 0 4px 24px;
    --shadow-hover: rgba(0, 0, 0, 0.45) 0 10px 32px;
  }
}

/* The surfaces nobody draws. These ship with browser defaults that belong to no design
   system, and theming them is the cheapest signal that a page was built rather than
   assembled. */
::selection {
  background: var(--accent-wash);
  color: var(--ink);
}

:root {
  accent-color: var(--accent);
  caret-color: var(--accent);
  scrollbar-color: var(--field-edge) transparent;
}

:where(a, button, input, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

a {
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
