/* Ibis tokens, the same names and values as the canvas (docs/design/foundations.md, "Tokens").
   Three layers, each value declared once:
     1 Primitives  raw values, named by what they are.
     2 Semantic    what a value is for, set per mode.
     3 Component   what a part needs, derived from layer 2 by a rule.
   Parts read layers 2 and 3 and the space scale. Sizes are in rem so the system
   and Larger text settings scale them; radii stay px, matching the native corner. */

/* Parameters: the few values a designer turns. Everything below derives
   from them or from Apple's own values, so one change restyles every part. */
:where([data-app-tokens]) {
  --unit: .25rem;        /* the spacing grid (4 pt) */
  --radius: 8px;         /* a control's corner; the two other corners follow */
  --type-base: .8125rem; /* body text (13 pt); every text style steps from it */
  --ibis: #c23a1c; --ibis-dark: #f2552f; /* Ibis red, light and dark (brand/settings.json) */
}

/* Layer 1: primitives. */
:where([data-app-tokens]) {
  /* Space, on the grid. S = --inset keeps every fill S from a window edge or divider. */
  --space-1: var(--unit); --space-2: calc(2 * var(--unit)); --space-3: calc(3 * var(--unit)); --space-4: calc(4 * var(--unit));
  --space-5: calc(5 * var(--unit)); --space-6: calc(6 * var(--unit)); --space-8: calc(8 * var(--unit)); --space-10: calc(10 * var(--unit));
  /* Layout (maintainer, 2026-11-10): where things sit, decided here once. Only ui/
     parts read these; a screen never sets a margin, padding, gap, inset or width
     (ui/ownership.test.ts). The window inset, on both sides of every band and body. */
  --inset: var(--space-2);
  /* The space between sections, columns and groups. */
  --gutter: var(--space-4);
  /* A row: its own padding, the gap after its icon slot (--tile), its spacing in a
     list, and its two heights. Rows without an icon start their words at
     --inset + --row-pad; rows with one start them on the label column after the slot. */
  --row-pad: var(--space-3); --row-gap: var(--space-3); --row-spacing: 2px;
  --row-compact: var(--space-10); --row-comfortable: 3.625rem;
  --row-height: var(--row-comfortable);
  /* The longest a sheet's text and cards run before the window has more room. */
  --content-max: 42rem;
  --larger-text-scale: 1.15;

  /* Sizes. */
  /* --tile is the icon slot: every row's icon, the bird and the back chevron centre on it. */
  --tile: var(--space-8); --icon: 16px; --icon-tile: 20px; --icon-stroke: 1.5; --key: var(--space-5);
  --control-h: var(--space-8); --action-h: 1.75rem; --control-small-h: var(--space-6); --field-h: 2.25rem; --touch-target: 2.75rem; --border-width: 1px;
  --status-dot: var(--space-2);
  /* A control's hit area: 32 px, 44 px under a coarse pointer. */
  --hit: var(--control-h);
  /* The narrowest a status line (library, project) shrinks before it wraps. */
  --status-min: 14rem;
  /* The shortest a status gets before the footer folds its hint labels to keys:
     about a word, never a stub such as "Z…". */
  --status-short: 6rem;
  /* Measured from NSSwitch on macOS 26: a wide capsule with a pill thumb. */
  --switch-w: 54px; --switch-h: 24px; --switch-thumb-w: 32px; --switch-thumb-h: 20px;
  /* The search glyph sits on the tile column and the query on the title column. */
  --lead: calc(var(--row-pad) + (var(--tile) - var(--icon-tile)) / 2);
  --lead-gap: calc((var(--tile) - var(--icon-tile)) / 2 + var(--row-gap));
  /* [C3] From a row's content edge: where its title starts, and the inset that
     centres a mark of width W on the tile column is (--tile - W) / 2. The footer
     and its notices use the same two columns as the rows above them. */
  --title-start: calc(var(--tile) + var(--row-gap));
  /* [C20] The reader: a page at Fit Width and its thumbnail. Paper is drawn as the
     PDF draws it, white in either mode, with ink to match. */
  --page-w: 34rem; --thumb-w: 4rem;
  --paper: #ffffff; --paper-ink: #2b2b2b; --paper-ink-secondary: #6e6e73;

  /* Corners: three steps from --radius, plus the window's (the Mac's own, matching
     the native mask [C15]), a capsule and the app icon's. Nested shapes are
     concentric: a shape --space-2 inside a --r-large one takes --r-control, a mark
     a few pixels inside a control takes --r-small.
       window 16 -8-> row, field, control 8 -2-> segment, key cap 6
       menu, card, sheet 12 -4-> menu item 8     row 8 -> tile 6 */
  --r-small: calc(.75 * var(--radius)); --r-control: var(--radius); --r-large: calc(1.5 * var(--radius));
  --r-win: 16px; --r-full: 999px; --r-icon: 22.5%;

  /* Type: size / line, as macOS text styles step from body (1 pt = .0625rem).
     Nothing is smaller than 12 px. */
  --type-body-size: var(--type-base); --type-body-line: calc(var(--type-base) + .1875rem);
  --type-label-size: calc(var(--type-base) - .0625rem); --type-label-line: calc(var(--type-label-size) + .1875rem);
  --type-title-size: calc(var(--type-base) + .125rem); --type-title-line: calc(var(--type-title-size) + .3125rem);
  --type-lead-size: calc(var(--type-base) + .25rem); --type-lead-line: calc(var(--type-lead-size) + .3125rem);
  --type-display-size: calc(var(--type-base) + .4375rem); --type-display-line: calc(var(--type-display-size) + .375rem);
  --type-search-size: calc(var(--type-base) + .5625rem); --type-search-line: calc(var(--type-search-size) + .25rem);
  --strong: 600;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;

  /* Motion (docs/design/foundations.md, "Motion"): three steps. --dur-1 answers a
     touch (hover, press, a check drawing); --dur-2 brings something in (a menu
     growing from its button, a line appearing); --dur-3 moves a region (a sheet,
     a panel). Entrances ease out, exits ease in, and something that follows the
     pointer or the keys settles on a spring with no overshoot. */
  --dur-1: 120ms; --dur-2: 180ms; --dur-3: 240ms;
  --ease-out: cubic-bezier(.2, .8, .2, 1); --ease-in: cubic-bezier(.4, 0, 1, 1);
  --ease-spring: linear(0, .25 7%, .54 16%, .77 27%, .9 39%, .97 53%, .995 70%, 1);
  /* A pressed control gives a little, as a key does. */
  --press-scale: .97;

  /* Layers. */
  --z-chrome: 1; --z-overlay: 10; --z-modal: 30;

  --white: #fff;

  /* Depth. */
  --shadow-card: 0 0 0 .5px rgb(0 0 0 / 10%), 0 1px 2px rgb(0 0 0 / 8%), 0 8px 20px -8px rgb(0 0 0 / 18%);
  --shadow-overlay: 0 0 0 .5px rgb(0 0 0 / 12%), 0 12px 32px rgb(0 0 0 / 16%);
  --shadow-toast: 0 8px 16px rgb(0 0 0 / 18%);
  --shadow-thumb: 0 0 0 .5px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 22%);
  --thumb: var(--white);
  --blur: none;

  /* Focus: one ring, keyboard only. */
  --ring-width: 2px; --ring-offset: 1px;
  /* A ring drawn inside a control that sits flush with its neighbours. */
  --ring-inside: calc(-1 * var(--ring-width));

  /* Colour: Apple's semantic ladders as measured from AppKit on macOS 27.2
     (docs/design/foundations.md, "Exact macOS values"), raised only where Ibis's floors need it.
     System colours sit underneath for webviews without light-dark(). */
  --surface: Canvas; --surface-overlay: Canvas;
  --text: CanvasText; --text-secondary: CanvasText; --text-tertiary: CanvasText; --text-disabled: GrayText;
  --separator: GrayText; --stroke-field: transparent;
  --accent: Highlight; --accent-text: var(--accent); --text-on-accent: HighlightText;
  /* Rings and marks drawn in the accent, with no text on them: they need 3:1, never 4.5:1 under white. */
  --accent-mark: var(--accent);
  --selected: Highlight; --selected-text: HighlightText; --selected-text-secondary: currentColor;
  --text-placeholder: var(--text-secondary);
  --ring: var(--accent-text);
  --scarlet: CanvasText; --on-scarlet: var(--white);
  --status-ok: CanvasText; --status-warning: CanvasText; --status-error: CanvasText;
  /* System, secondary, tertiary and quaternary fill. */
  --fill-1: color-mix(in srgb, var(--text) 9.8%, transparent);
  --fill-2: color-mix(in srgb, var(--text) 7.8%, transparent);
  --fill-3: color-mix(in srgb, var(--text) 4.7%, transparent);
  --fill-4: color-mix(in srgb, var(--text) 2.7%, transparent);
  /* Controls rest, hover and press on the tertiary, secondary and system fills. */
  --fill-control: var(--fill-3); --fill-control-hover: var(--fill-2); --fill-control-pressed: var(--fill-1);
  --fill-quiet-hover: var(--fill-4);
  --surface-field: var(--fill-control); --chip: var(--fill-control-hover);
  --on-fill-h: rgb(0 0 0 / 8%); --on-fill-p: rgb(0 0 0 / 16%);
  --accent-wash: color-mix(in srgb, var(--accent) 14%, transparent);
  --on-selected-fill: color-mix(in srgb, var(--selected-text) 22%, transparent);
  --status-ok-wash: color-mix(in srgb, var(--status-ok) 9%, transparent);
  --status-ok-fill: color-mix(in srgb, var(--status-ok) 14%, transparent);
  --scrollbar-thumb: var(--text-tertiary);
  --scroll-fade: 14px;

  /* Settings: a grouped form beside a sidebar. Groups are Apple's tertiary fill,
     a step above the sidebar's quaternary, so they separate by fill, not by their edge. */
  --surface-grouped: var(--fill-3);
  /* Only macOS draws its window buttons over the content (settings_window.rs). */
  --titlebar-height: 0px;
  --sidebar-width: min(12.5rem, 26%);
  --page-general: #8e8e93; --page-look: #ff9f0a; --page-citations: #0a84ff; --page-shortcuts: #5e5ce6; --page-about: var(--page-general);
  --highlight: var(--accent-wash);
  /* Previews: the real part at one size each. The window picture keeps Medium's shape. */
  --preview-window-w: 45rem; --preview-window-h: 30rem;
  --preview-window: .21; --preview-thumb: .09; --preview-live: .42;
  /* The bird: the app icon names Ibis; the depth mark greets. */
  --mark-app: 6rem; --mark-greeting: 3.5rem;

}

/* Reduce Motion: feedback becomes a short fade, and anything that moves ends at once. */
@media (prefers-reduced-motion: reduce) { :where([data-app-tokens]) { --dur-1: 100ms; --dur-2: 1ms; --dur-3: 1ms; --press-scale: 1; } }
@media (pointer: coarse) { :where([data-app-tokens]) { --hit: var(--touch-target); } }
:where([data-app-tokens])[data-system="macos"] { --titlebar-height: var(--touch-target); }

/* The canvas's light and dark values. */
@supports (color: light-dark(white, black)) {
  :where([data-app-tokens]) {
    --scarlet: light-dark(var(--ibis), var(--ibis-dark));
    --status-ok: light-dark(#34c759, #30d158); --status-warning: light-dark(#ffcc00, #ffd600); --status-error: light-dark(#ff383c, #ff4245);
    --accent: #007aff; --accent-text: light-dark(#0068da, #419cff);
    --selected: light-dark(#0064e1, #0059d1); --selected-text: #fff; --text-on-accent: var(--selected-text);
    --selected-text-secondary: var(--selected-text);
  }
}
@supports (color: light-dark(white, black)) {
  @media (prefers-contrast: no-preference) and (forced-colors: none) {
    :where([data-app-tokens]) {
      --surface: light-dark(#ffffff, #1e1e1e);
      /* The raised layer for everything that floats: a step off the window in
         either mode, as a Mac menu is, never the window's own white or black. */
      --surface-overlay: light-dark(#f6f6f7, #2c2c2e);
      --text: light-dark(rgb(0 0 0 / 84.7%), rgb(255 255 255 / 84.7%));
      /* Darker than Apple's 50% in light: without vibrancy behind text it fell to 3.8:1 on the glass. */
      --text-secondary: light-dark(rgb(0 0 0 / 60%), rgb(255 255 255 / 54.9%));
      --text-tertiary: light-dark(rgb(0 0 0 / 25.9%), rgb(255 255 255 / 24.7%));

      --text-disabled: light-dark(rgb(0 0 0 / 24.7%), rgb(255 255 255 / 24.7%));
      --separator: light-dark(rgb(0 0 0 / 10%), rgb(255 255 255 / 12%));
      --fill-1: light-dark(rgb(0 0 0 / 9.8%), rgb(255 255 255 / 9.8%));
      --fill-2: light-dark(rgb(0 0 0 / 7.8%), rgb(255 255 255 / 7.8%));
      --fill-3: light-dark(rgb(0 0 0 / 4.7%), rgb(255 255 255 / 4.7%));
      --fill-4: light-dark(rgb(0 0 0 / 2.7%), rgb(255 255 255 / 2.7%));
      /* Dark separates less per step, so groups take one fill more there: 1.11:1 against the window in light, 1.25:1 in dark. */
      --surface-grouped: light-dark(var(--fill-3), var(--fill-2));
      --shadow-overlay: 0 0 0 .5px light-dark(rgb(0 0 0 / 12%), rgb(255 255 255 / 10%)), 0 12px 32px light-dark(rgb(0 0 0 / 16%), rgb(0 0 0 / 45%));
      /* The veil over the native material, so text stays legible on any wallpaper. */
      --vibrancy-tint: light-dark(rgb(250 250 252 / 75%), rgb(30 30 34 / 75%));
      --glass-edge: light-dark(rgb(0 0 0 / 10%), rgb(255 255 255 / 10%));
    }
  }
}

/* The accent is blue until the Mac's own arrives (nativeAccent.ts) or Look chooses one. */
/* WKWebView resolves AccentColorText to black, so macOS uses its list colours. */
@supports (background: -apple-system-selected-content-background) and (color: -apple-system-alternate-selected-text) {
  :where([data-app-tokens])[data-system="macos"] { --selected: -apple-system-selected-content-background; --selected-text: -apple-system-alternate-selected-text; }
}
/* Other systems keep their own selection pair. */
:where([data-app-tokens])[data-system="windows"], :where([data-app-tokens])[data-system="linux"] { --accent: Highlight; --selected: Highlight; --selected-text: HighlightText; }
/* As the Mac accent is, a system accent keeps 3:1 on the window: no lighter than
   oklch .62 in light (about 3.6:1 on white), no darker than .6 in dark. */
@supports (color: light-dark(oklch(from white l c h), black)) {
  /* Light: darken until the accent clears 3:1 and white on it reads. Dark: only
     rings and marks are lifted to 3:1; a fill keeps the system accent so white
     text on it does not drop below 4.5:1. */
  :where([data-app-tokens])[data-system="windows"], :where([data-app-tokens])[data-system="linux"] {
    --accent: light-dark(oklch(from Highlight min(l, .62) c h), Highlight);
    --accent-mark: light-dark(oklch(from Highlight min(l, .62) c h), oklch(from Highlight max(l, .6) c h));
  }
}
:where([data-app-tokens])[data-system="windows"] { --font: "Segoe UI Variable Text", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif; }
:where([data-app-tokens])[data-system="linux"] { --font: system-ui, "Adwaita Sans", Cantarell, sans-serif; }

/* Only a panel material that really applied can supply glass. */
@supports (color: light-dark(white, black)) and ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  @media (prefers-contrast: no-preference) and (forced-colors: none) and (prefers-reduced-transparency: no-preference) {
    :where([data-app-tokens])[data-platform="macos"][data-native-appearance="vibrancy"]:not(.notice-window),
    :where([data-app-tokens])[data-platform="macos"][data-native-appearance="liquid-glass"]:not(.notice-window) {
      --surface-overlay: light-dark(rgb(246 246 247 / 92%), rgb(44 44 46 / 92%));
      --blur: blur(40px) saturate(1.6);
    }
  }
}

/* Increase Contrast and forced colours: system colours, solid edges, no depth. */
@media (prefers-contrast: more), (forced-colors: active) {
  :where([data-app-tokens]), :where([data-app-tokens])[data-platform] {
    --shadow-card: none; --shadow-overlay: none; --shadow-toast: none; --shadow-thumb: none;
    --surface: Canvas; --surface-overlay: Canvas; --surface-grouped: Canvas;
    --text: CanvasText; --text-secondary: CanvasText; --text-tertiary: CanvasText; --separator: CanvasText; --stroke-field: CanvasText;
    --selected: Highlight; --selected-text: HighlightText; --selected-text-secondary: currentColor;
    --ring: CanvasText; --ring-offset: 2px; --scrollbar-thumb: CanvasText;
    --scarlet: CanvasText; --on-scarlet: Canvas;
    --status-ok: CanvasText; --status-warning: CanvasText; --status-error: CanvasText;
  }
}
/* Increase Contrast keeps groups apart by fill too: the system fill, over the solid edge. */
@media (prefers-contrast: more) and (forced-colors: none) {
  :where([data-app-tokens]), :where([data-app-tokens])[data-platform] { --surface-grouped: var(--fill-1); }
}
@media (forced-colors: active) {
  :where([data-app-tokens]), :where([data-app-tokens])[data-platform] { --stroke-field: ButtonText; --separator: ButtonText; --on-fill-h: transparent; --on-fill-p: transparent; }
}

@supports (color: light-dark(white, black)) {
  @media (prefers-contrast: more) and (forced-colors: none) {
    :where([data-app-tokens]), :where([data-app-tokens])[data-platform] {
      --status-ok: light-dark(#1a7f37, #5bdf7d);
      --status-warning: light-dark(#8a6400, #ffe14c);
      --status-error: light-dark(#b91c35, #ff6961);
    }
  }
}

/* One accent, three roles, both modes: the accent colours controls and the focus
   ring; the selection is a deeper shade that keeps its text at 4.5:1; accent text
   passes 4.5:1 on the surface. Follow the Mac reaches these roles from
   the native accent below; Ibis scarlet is the one fixed choice, following the same rule:
   selection and filled controls carry white, and the bright scarlet stays for
   accent text, the ring and marks in dark. */
@supports (color: light-dark(white, black)) {
  @media (prefers-contrast: no-preference) and (forced-colors: none) {
    :where([data-app-tokens])[data-appearance][data-accent="ibis"]:not(.notice-window) {
      --accent: light-dark(var(--ibis), var(--ibis-dark)); --accent-text: var(--accent);
      --selected: var(--ibis); --primary: var(--selected); --selected-text: #fff; --text-on-accent: var(--selected-text);
    }
  }
}
/* Every window: light-dark() has no value without a scheme. */
:where([data-app-tokens]) { color-scheme: light dark; }
:where([data-app-tokens])[data-appearance="light"] { color-scheme: light; }
:where([data-app-tokens])[data-appearance="dark"] { color-scheme: dark; }
:where([data-app-tokens]).settings-window[data-larger-text="true"] { font-size: calc(100% * var(--larger-text-scale)); }

/* Layer 3: components, derived from the layers above. */
:where([data-app-tokens]) {
  --key-gap: calc((var(--control-small-h) - var(--key)) / 2);
  /* Layout: the header (the search field's band) and the footer band, and where a
     section's heading and words start: on the text of the rows in its card. */
  --header-h: calc(var(--field-h) + 2 * var(--inset) + var(--border-width));
  --footer-h: calc(var(--control-small-h) + 2 * var(--inset));
  --heading-offset: calc(var(--row-pad) + var(--border-width));
  --inspector-width: 18rem; --inspector-column: 15rem;
  /* Measured from NSSegmentedControl: the chosen fill lands at 19% of the text colour. */
  --segment-selected: color-mix(in srgb, var(--text) 12%, transparent);
  --primary: var(--accent);
  --accent-hover: color-mix(in srgb, var(--primary) 90%, black);
  --accent-pressed: color-mix(in srgb, var(--primary) 80%, black);
}

/* The website's reading rhythm; page composition stays in website/style.css. */
:where([data-app-tokens]) {
  --font-reading: "Iowan Old Style", Charter, "Palatino Linotype", Cambria, Georgia, serif;
  --type-reading-size: 1rem; --type-heading-size: 1.25rem;
  --website-margin: 17rem; --website-gap: clamp(2rem, 4.5vw, 4rem);
  --website-pad: clamp(1.25rem, 3.5vw, 3.5rem);
  --website-paragraph-gap: 1.1rem; --website-block-gap: 1.25rem;
  --website-section-pad: clamp(1.5rem, 3vw, 2.25rem);
  --website-chip-radius: 5px; --website-press: .96; --website-reveal: 12px;
  --website-button-height: 2.25rem;
}

/* The Mac's own accent (nativeAccent.ts), once a validated native snapshot arrives,
   unless Look chose Ibis scarlet: that choice wins whatever the order of the rules. */
/* Private inputs are unset until a validated native snapshot arrives. These
   guards preserve all system pairs, in high contrast. */
:where([data-app-tokens]) { --native-accent-fill: initial; --native-accent-on: initial; --native-accent-light: initial; --native-accent-dark: initial; }
@supports (color: light-dark(white, black)) {
  @media (prefers-contrast: no-preference) and (forced-colors: none) {
    :where([data-app-tokens])[data-native-accent="true"][data-platform="macos"]:not(.notice-window, [data-accent="ibis"]) {
      --accent: var(--native-accent-fill);
      --accent-text: light-dark(var(--native-accent-light), var(--native-accent-dark));
      --text-on-accent: var(--native-accent-on);
      --selected: var(--accent); --selected-text: var(--text-on-accent);
    }
    /* macOS keeps WebKit's selection pair: deeper than the accent, and it follows it. */
    @supports (background: -apple-system-selected-content-background) and (color: -apple-system-alternate-selected-text) {
      :where([data-app-tokens])[data-native-accent="true"][data-system="macos"]:not(.notice-window, [data-accent="ibis"]) {
        --selected: -apple-system-selected-content-background;
        --selected-text: -apple-system-alternate-selected-text;
      }
      /* An accent too bright for white text fills the primary with that deeper pair. */
      :where([data-app-tokens])[data-native-accent-deep="true"][data-system="macos"]:not(.notice-window, [data-accent="ibis"]) {
        --primary: var(--selected); --text-on-accent: var(--selected-text);
      }
    }
  }
}
@media (prefers-contrast: more), (forced-colors: active) {
  :where([data-app-tokens]), :where([data-app-tokens])[data-platform] { --accent: Highlight; --accent-text: CanvasText; --text-on-accent: HighlightText; }
}

/* Windows Acrylic: a guarded veil, so text keeps its roles over any backdrop (ui/Material.css). */
@supports (color: light-dark(white, black)) {
  @media (forced-colors: none) and (prefers-contrast: no-preference) {
    :where([data-app-tokens])[data-system="windows"][data-native-appearance="acrylic"]:not(.notice-window) {
      --acrylic-tint: light-dark(rgb(249 249 249 / 92%), rgb(40 40 40 / 92%));
    }
  }
}

/* BEGIN generated website palette: brand/build.py */
:where([data-app-tokens]) {
  --website-bg: Canvas;
  --website-surface: Canvas;
  --website-line: GrayText;
  --website-text: CanvasText;
  --website-muted: CanvasText;
  --website-accent-soft: Canvas;
}
@supports (color: light-dark(white, black)) {
  @media (forced-colors: none) {
    :where([data-app-tokens]) {
      --website-bg: light-dark(#FFFFFF, #111111);
      --website-surface: light-dark(#F5F5F5, #1C1C1C);
      --website-line: light-dark(#E5E5E5, #2E2E2E);
      --website-text: light-dark(#171717, #F2F2F2);
      --website-muted: light-dark(#525252, #B5B5B5);
      --website-accent-soft: light-dark(rgb(194 58 28 / .08), rgb(242 85 47 / .13));
    }
  }
}
/* END generated website palette */
