/* Resonance: the whole page is a Chladni plate behind the text. The text blocks are held still (the sand is shaken
   off them), so they always sit on clear plate; the mode caption sits in the bottom corner. */
/* Fonts are self-hosted (SIL Open Font License, see fonts/OFL-*.txt): the page makes no third-party requests.
   Inter Tight is a variable font, one file covers 400 and 500. */
@font-face { font-family: "Inter Tight"; font-style: normal; font-weight: 400 500; font-display: swap;
  src: url("../fonts/inter-tight-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Inter Tight"; font-style: normal; font-weight: 400 500; font-display: swap;
  src: url("../fonts/inter-tight-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  --bg: #0b0b0c; --plate: #121214; --sand: #ece7dc; --ink: #ece7dc; --dim: #8a867d; --faint: #4a4844;
  --line: #222225; --accent: #f06a2e;
  --sans: "Inter Tight", ui-sans-serif, system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
  color-scheme: dark;
}
/* Light: dark sand on warm paper. Follows the system unless the visitor picks a theme with the toggle. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
  --bg: #eceae4; --plate: #e4e1d9; --sand: #1c1a17; --ink: #171614; --dim: #5f5c55; --faint: #aaa69c;
    --line: #d3cfc6; --accent: #b5370f;
    color-scheme: light;
  }
}
:root[data-theme="light"] {
  --bg: #eceae4; --plate: #e4e1d9; --sand: #1c1a17; --ink: #171614; --dim: #5f5c55; --faint: #aaa69c;
  --line: #d3cfc6; --accent: #b5370f;
  color-scheme: light;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 16px/1.6 var(--sans); -webkit-font-smoothing: antialiased; }
a { color: inherit; }
:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }

/* The plate is drawn over the page (sand never lands on text, see resonance.js), so on phones it can show above
   the index as it fades out under the window at the top. */
#plate { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 2; pointer-events: none; }
.window, .playground { display: none; }
/* Open plate takes a drawn line (resonance.js); the text and controls keep their own cursor. */
html { cursor: crosshair; }
.head, nav, .controls, #mode { cursor: auto; }
#mode { position: fixed; right: clamp(16px, 3vw, 28px); bottom: 14px; margin: 0; z-index: 3;
  font: 12px/1 var(--mono); color: var(--dim); letter-spacing: 0.02em; }
#mode b { color: var(--accent); font-weight: 400; }
#mode .worn { opacity: 0.5; }
#mode .now { color: var(--ink); } /* the shell a drawn figure rests on now */
.controls { position: fixed; top: 14px; right: clamp(16px, 3vw, 28px); z-index: 3; display: flex; gap: 18px; }
.controls button { margin: 0; padding: 4px 0; font: 12px/1 var(--mono); color: var(--dim); background: none; border: 0; cursor: pointer; }
.controls button:hover, .controls button:focus-visible { color: var(--ink); }
.controls button[hidden] { display: none; }
.controls button[aria-expanded="true"] { color: var(--ink); }

/* How it works: a quiet panel under the controls, closed by default (resonance.js). The sand keeps off it. */
.how { position: fixed; top: 44px; right: clamp(16px, 3vw, 28px); z-index: 4; width: min(23rem, calc(100vw - 32px));
  max-height: calc(100vh - 88px); overflow-y: auto; padding: 18px 20px 4px; background: var(--bg);
  border: 1px solid var(--line); color: var(--dim); font-size: 14px; line-height: 1.55; cursor: auto; }
.how[hidden] { display: none; }
.how:focus { outline: none; }
.how h2 { margin: 0 0 12px; font: 12px/1.5 var(--mono); color: var(--ink); font-weight: 400; }
.how p { margin: 0 0 14px; text-wrap: pretty; }
.how p:first-of-type { color: var(--ink); }

.wrap { position: relative; padding: 0 clamp(16px, 7vw, 120px); pointer-events: none; }
.text { width: min(100%, 30rem); padding: 18vh 0 30vh; }
.head, nav { pointer-events: auto; width: fit-content; max-width: 100%; }
nav { width: 100%; }

h1 { font-size: 15px; font-weight: 500; margin: 0 0 28px; letter-spacing: 0.01em; }
.intro { font-size: clamp(34px, 4.4vw, 56px); line-height: 1.05; letter-spacing: -0.025em; margin: 0 0 22px; font-weight: 500; text-wrap: balance; }
.about { color: var(--dim); margin: 0 0 22px; max-width: 26rem; text-wrap: pretty; }
.contact { display: flex; flex-wrap: wrap; gap: 6px 24px; margin: 0 0 64px; font-size: 14px; }
.contact a { color: var(--dim); text-decoration: none; border-bottom: 1px solid var(--line); }
.contact a:hover, .contact a:focus-visible { color: var(--ink); border-color: var(--accent); }

.label { margin: 0 0 10px; font: 12px/1.5 var(--mono); color: var(--dim); }
.label span { color: var(--dim); }
.projects { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.projects a {
  display: grid; grid-template-columns: 2.2em minmax(6em, 8em) 1fr auto 3em; gap: 12px; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid var(--line); text-decoration: none;
}
.n, .m, .year { font: 12px/1 var(--mono); color: var(--dim); }
.m { color: var(--dim); }
.year { text-align: right; }
.name { font-weight: 500; transition: color .2s; }
.desc { color: var(--dim); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projects a:hover .name, .projects a:focus-visible .name, .projects a.on .name { color: var(--accent); }
.projects a.on .m { color: var(--accent); }
.projects a:focus-visible { outline-offset: -1px; }
/* Reserved frequencies: the next rows of the index, a number, a quiet line and the mode waiting for a project. */
.reserved { display: grid; grid-template-columns: 2.2em 1fr auto 3em; gap: 12px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid var(--line); }
.reserved .n, .reserved .m { color: var(--faint); }
.reserved .rule { height: 1px; width: min(8em, 40%); background: var(--line); }
.reserved.on .m, .reserved.on .n { color: var(--accent); }
.reserved.on .rule { background: var(--accent); }

@media (max-width: 760px) {
  .wrap { padding: 0 16px; }
  .text { padding: 48vh 0 0; } /* open plate above the text on load */
  /* The plate window takes a finger for drawing, so the page scrolls from the text below it. */
  .window { display: block; position: fixed; inset: 0 0 auto; height: 44vh; z-index: 1; touch-action: none;
    background: linear-gradient(var(--bg) 80%, transparent); }
  /* At the end of the page the open plate under the index is the playground: it takes a finger for drawing, and
     the window at the top lets the page scroll back instead (resonance.js sets .at-end). */
  .playground { display: block; height: 52vh; margin-top: 8vh; pointer-events: auto; cursor: crosshair; }
  /* a finger there scrolls until the end is reached; only then does it draw (Codex review) */
  .at-end .playground { touch-action: none; }
  .at-end .window { pointer-events: none; touch-action: auto; }
  /* Controls: 44px tap targets at 12px text (13px would not fit four of them at 320px wide); the caption has its own
     line under them, clear of the index (Codex review, 2026-10-04). */
  .controls { left: 16px; right: 16px; top: calc(14px + env(safe-area-inset-top, 0px));
    justify-content: space-between; flex-wrap: nowrap; gap: 4px; }
  .controls button { flex: 0 0 auto; min-width: 44px; min-height: 44px; padding: 14px 0; line-height: 16px; }
  #mode { left: 16px; right: 16px; top: calc(64px + env(safe-area-inset-top, 0px)); bottom: auto;
    font-size: 13px; line-height: 18px; overflow-wrap: anywhere; }
  .how { top: calc(64px + env(safe-area-inset-top, 0px)); left: 16px; right: 16px; width: auto;
    max-height: calc(100vh - 80px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)); }
  .intro { font-size: 34px; }
  .label { font-size: 13px; line-height: 20px; }
  /* Each project row: number, name, mode and year, with what the project is on a second line under the name. */
  .projects a { grid-template-columns: 2.2em minmax(0, 1fr) auto 3em; gap: 4px 12px; }
  .projects .n { grid-area: 1 / 1; }
  .projects .name { grid-area: 1 / 2; line-height: 24px; }
  .projects .m { grid-area: 1 / 3; }
  .projects .year { grid-area: 1 / 4; }
  .n, .m, .year { font-size: 13px; line-height: 18px; }
  .projects .desc { grid-area: 2 / 2 / 3 / -1; line-height: 20px; white-space: normal; overflow: visible; }
}
