/* Revibing HCI, UIST 2026.
   One style, driven entirely by the tokens on .page. Everything below reads
   tokens, so a variant is a token block. */

/* Each file holds one weight, so each weight needs its own rule. Declaring a
   range here would make the browser reuse the regular for headings, which is
   what made the first headings look thin. */
@font-face { font-family: "Schibsted Grotesk"; font-style: normal; font-weight: 400; font-display: swap; src: url(assets/fonts/schibsted.woff2) format("woff2"); }
@font-face { font-family: "Schibsted Grotesk"; font-style: normal; font-weight: 600; font-display: swap; src: url(assets/fonts/schibsted-600.woff2) format("woff2"); }
@font-face { font-family: "DM Mono";           font-style: normal; font-weight: 400; font-display: swap; src: url(assets/fonts/dmmono-normal.woff2) format("woff2"); }

* { box-sizing: border-box; }

.page {
  --ground: #F6F6F6; --band: #FFFFFF; --ink: #0B0B0C; --muted: #5E6062;
  --faint: #6E7072; --rule: #DEDEDE; --accent: #0B0B0C; --tint: #ECECEC;
  --surface: #FFFFFF; --acc: #2743D6; --on-acc: #FFFFFF;
  --r: 22px; --pill: 999px;
  --display: "Schibsted Grotesk", system-ui, sans-serif; --display-w: 600; --display-ls: -.025em;
  --ui: "Schibsted Grotesk", system-ui, sans-serif;
  --read: "Schibsted Grotesk", system-ui, sans-serif;
  --mono: "DM Mono", ui-monospace, Menlo, monospace;
  --ease: cubic-bezier(.32, .08, .24, 1);
  --h1: clamp(2rem, 1.2rem + 2.6vw, 3.2rem);
  --h2: clamp(1.35rem, 1.1rem + .9vw, 1.8rem);
  --w: 600;
  background: var(--ground); color: var(--ink);
  font-family: var(--read); font-size: 1rem; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
body { margin: 0; background: var(--page-bg, #FFF); }
/* paragraphs start with no margin. Anything that needs one says so with a
   `.page` prefix, because this rule outranks a bare class selector. */
.page p { margin: 0; }
.page h1, .page h2, .page h3 { margin: 0; font-family: var(--display); font-weight: var(--display-w); letter-spacing: var(--display-ls); line-height: 1.08; text-wrap: balance; }
.page h1 { font-size: var(--h1); }
.page h2 { font-size: var(--h2); }
.page a { color: var(--acc); text-decoration: none; }
.page a:hover { text-decoration: underline; }
.page :focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; }

.wrap { max-width: 62rem; margin: 0 auto; padding-inline: clamp(1rem, 4vw, 2rem); }

/* ---------- nav ---------- */
.nav { border-bottom: 1px solid var(--rule); background: var(--ground); position: sticky; top: 0; z-index: 20; }
.nav-in { max-width: 62rem; margin: 0 auto; padding: .6rem clamp(1rem, 4vw, 2rem); display: flex; align-items: center; gap: .9rem; }
.nav .mark { font-family: var(--ui); font-size: .9375rem; font-weight: var(--w); color: var(--ink); }
.nav ul { list-style: none; display: flex; gap: 1.15rem; margin: 0 0 0 auto; padding: 0; }
.nav ul a { font-family: var(--ui); font-size: .875rem; color: var(--muted); }
.nav ul a:hover { color: var(--ink); text-decoration: none; }
@media (max-width: 860px) { .nav ul { display: none; } }

.page .btn {
  display: inline-flex; align-items: center; gap: .35rem; font-family: var(--ui);
  font-size: .9375rem; font-weight: var(--w); padding: .52rem 1.05rem;
  border-radius: var(--pill); border: 1px solid var(--acc);
  background: var(--acc); color: var(--on-acc); cursor: pointer;
}
.page .btn:hover { text-decoration: none; opacity: .9; }
.page .btn.line { background: transparent; color: var(--ink); border-color: var(--rule); }
.page .btn.line:hover { border-color: var(--ink); opacity: 1; }
.nav .btn { margin-left: .3rem; padding: .4rem .9rem; font-size: .8125rem; }

/* ---------- hero ---------- */
.hero { padding: clamp(1.75rem, 4vw, 3rem) 0 0; position: relative; overflow: hidden; }
.hero-in, .details-wrap { position: relative; }
.details-wrap { pointer-events: auto; }
/* a full width bed under the facts strip: the field fades into plain page colour
   before it, so that row is always legible whatever the wave is doing */
.details-bed {
  /* This is a wash, nothing more. The negative margin pulls it up over the last
     4rem of the hero panel, so without this it takes clicks meant for whatever
     is under there. It swallowed the paper's own link once already. */
  pointer-events: none;
  position: relative; padding-top: 4rem; margin-top: -4rem;
  background: linear-gradient(180deg, transparent 0%,
    color-mix(in srgb, var(--ground) 10%, transparent) 20%,
    color-mix(in srgb, var(--ground) 30%, transparent) 40%,
    color-mix(in srgb, var(--ground) 58%, transparent) 58%,
    color-mix(in srgb, var(--ground) 82%, transparent) 74%,
    var(--ground) 90%);
}
/* the copy keeps a measured column, which leaves the right of the hero to the
   field. Events pass through the container so field glyphs there stay
   hoverable, and every child takes its own events back. */
.hero-in { pointer-events: none; }
.hero-in > * { pointer-events: auto; }
.hero-copy { max-width: 36rem; position: relative; }
.page .eyebrow { font-family: var(--mono); font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: .8rem; }
.hero .sub { margin-top: .45rem; font-size: clamp(1rem, .95rem + .45vw, 1.25rem); color: var(--muted); }
.hero .lede { margin-top: 1.1rem; max-width: 50ch; font-size: clamp(1rem, .95rem + .25vw, 1.1rem); line-height: 1.5; }
.hero .acts { margin-top: 1.3rem; display: flex; flex-wrap: wrap; gap: .5rem; }

/* the ambient field: papers on the shelf, coming back as running systems.
   It sits behind the hero copy, and the mask keeps it out of the way of text. */
.hero-field { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
/* A wash of the page colour that is solid over the words and dissipates outward
   in every direction, so the field is quietest where the text is and never shows
   an edge. The far corners keep a light veil, which is the last stop. */
.hero-field:after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(72% 92% at 32% 42%,
    var(--ground) 0%,
    var(--ground) 18%,
    color-mix(in srgb, var(--ground) 78%, transparent) 40%,
    color-mix(in srgb, var(--ground) 46%, transparent) 64%,
    color-mix(in srgb, var(--ground) 18%, transparent) 100%);
}
/* on a narrow screen the copy fills the width, so the wash centres on it */
@media (max-width: 700px) {
  .hero-field:after {
    background: radial-gradient(125% 78% at 50% 32%,
      var(--ground) 0%,
      var(--ground) 44%,
      color-mix(in srgb, var(--ground) 76%, transparent) 66%,
      color-mix(in srgb, var(--ground) 30%, transparent) 100%);
  }
}
.hf-grid {
  position: absolute; inset: -1.2rem -0.5rem -0.5rem -0.5rem;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(4.4rem, 1fr));
  grid-auto-rows: 3.7rem; align-items: center; justify-items: center;
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.45) 0%, #000 9%, #000 93%, rgba(0,0,0,.45) 100%);
  mask-image: linear-gradient(180deg, rgba(0,0,0,.45) 0%, #000 9%, #000 93%, rgba(0,0,0,.45) 100%);
}
.hf-cell { position: relative; width: 2rem; height: 2.1rem; pointer-events: auto; perspective: 260px; }
.hf-flip { position: absolute; inset: 0; display: grid; place-items: center; transform-style: preserve-3d; transition: transform .85s cubic-bezier(.4, 0, .2, 1); }
.hf-cell.on .hf-flip { transform: rotateY(180deg); }
.hf-face { position: absolute; display: grid; place-items: center; backface-visibility: hidden; }
.hf-face.back { transform: rotateY(180deg); }
.hf-face svg { display: block; }
.hf-paper { stroke: var(--faint); opacity: .5; transition: opacity .9s; }
.hf-sys { stroke: var(--acc); opacity: .62; transition: opacity .9s; }
/* the brief flare on whatever just changed, by the wave or by a hover */
.hf-cell.just .hf-paper { opacity: .8; transition-duration: .12s; }
.hf-cell.just .hf-sys { opacity: 1; transition-duration: .12s; }
.hf-cell { cursor: default; }
.hf-cell.stuck .hf-paper { opacity: .26; }

/* ---------- the hero visual: a paper, and the system it became ---------- */
.visual {
  position: relative; margin-top: clamp(1.2rem, 3vw, 1.9rem);
  border-radius: var(--r); overflow: hidden;
  background: color-mix(in srgb, var(--tint) 74%, transparent);
  /* the paper, what the agent did to it, and the thing it became */
  display: grid;
  grid-template-columns: minmax(0, 13rem) minmax(0, 11rem) minmax(0, 1fr);
  column-gap: clamp(.9rem, 2.2vw, 1.6rem); row-gap: .9rem;
  padding: clamp(1rem, 2.4vw, 1.6rem);
  align-items: center;
}
.rv-paper {
  position: relative; margin: 0; width: min(12.5rem, 100%); border-radius: 3px;
  overflow: hidden; border: 1px solid var(--rule); background: var(--surface);
  box-shadow: 0 8px 20px -16px rgba(0, 0, 0, .55);
  transform: rotate(-2.5deg) translateY(3px);
  transition: transform .55s var(--ease), box-shadow .55s;
}
.rv-paper.up { transform: none; box-shadow: 0 12px 26px -18px rgba(0, 0, 0, .5); }
.rv-paper img { width: 100%; height: auto; display: block; }
.rv-sweep {
  position: absolute; left: 0; right: 0; top: -20%; height: 16%; opacity: 0;
  background: color-mix(in srgb, var(--acc) 16%, transparent);
}
.rv-sweep.run { opacity: 1; transition: top .95s ease-in-out; top: 104%; }
/* the marks the reading pass leaves behind, as percentages of the page image */
.rv-mark { position: absolute; border-radius: 2px; opacity: 0; transition: opacity .3s; background: color-mix(in srgb, var(--acc) 26%, transparent); }
.rv-mark.on { opacity: 1; }
/* Positions come from measuring the ink in crossy-p1.jpg, not from eye. The two
   text columns are x 8.8% to 48.0% and x 52.1% to 90.9%, lines are 1.1% tall on
   a 1.5% pitch, and the figure occupies 51.8%, 31.8%, 39.1% by 21.6%. Each mark
   is two lines tall and starts on a line, so none of them cuts through text. */
.rv-mark.m1 { left: 8.7%; top: 33.0%; width: 38%; height: 2.8%; }
.rv-mark.m2 { left: 8.7%; top: 38.9%; width: 32%; height: 2.8%; }
.rv-mark.m3 { left: 51.9%; top: 60.4%; width: 37%; height: 2.8%; }
.rv-mark.m4 { left: 51.9%; top: 68.2%; width: 31%; height: 2.8%; }
.rv-figbox {
  position: absolute; left: 51.6%; top: 31.5%; width: 39.6%; height: 22.2%;
  border: 1.5px solid var(--acc); border-radius: 3px; opacity: 0;
  transition: opacity .35s; background: color-mix(in srgb, var(--acc) 8%, transparent);
}
.rv-figbox.on { opacity: .85; }

/* The caption is a row of its own under all three columns rather than a note
   stuck beside the paper. It describes the panel, not the page image, and it
   fits on one line at any width worth having. */
.rv-cap {
  grid-column: 1 / 3; grid-row: 2; font-family: var(--ui); font-size: .75rem;
  line-height: 1.4; color: var(--muted);
}
/* the paper's own title is the link to it, so it carries an underline. Every
   other paper name on the page stays plain until hover, but this one is the
   only route to the source and has to look like one. */
.page .rv-cap .rv-src {
  color: var(--ink); font-weight: var(--w);
  text-decoration: underline; text-underline-offset: .16em;
  text-decoration-thickness: 1px; text-decoration-color: var(--faint);
}
.page .rv-cap .rv-src:hover { text-decoration-color: var(--acc); color: var(--acc); }
/* The panel does not say what to do with it until it is finished being built,
   because an invitation to draw on something still assembling itself is noise.
   It sits directly under the interface it is talking about, in the accent, so
   it reads as the page speaking to the reader rather than more caption. */
.page .rv-try {
  grid-column: 3; grid-row: 2; margin: 0;
  font-family: var(--ui); font-size: .75rem; line-height: 1.4; color: var(--acc);
  opacity: 0; transition: opacity .6s var(--ease);
}
.rv-try.on { opacity: 1; }
.rv-try svg {
  width: 1.2rem; height: .72rem; display: inline-block; vertical-align: -.06em;
  margin-right: .3rem; fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- the terminal: what the agent was asked, and what it ran ----------
   It keeps its own dark palette rather than reading page tokens, because a
   terminal that turns white in one of the two styles stops being a terminal.
   The colours are a dark band a step below the page ground. */
.rv-term {
  --t-bg: #131419; --t-bar: #1D1E24; --t-rule: #2C2D35;
  --t-ink: #E4E6EB; --t-dim: #7B808B; --t-acc: #8E9BFF; --t-ok: #5BD08A;
  align-self: center; border-radius: 10px; overflow: hidden;
  background: var(--t-bg); border: 1px solid var(--t-rule);
  box-shadow: 0 16px 38px -26px rgba(0, 0, 0, .8);
}
.rv-tbar {
  display: flex; align-items: center; gap: .3rem;
  padding: .5rem .65rem; background: var(--t-bar);
  border-bottom: 1px solid var(--t-rule);
}
.rv-tdot { width: .4rem; height: .4rem; border-radius: 50%; background: #3A3C45; flex: none; }
.rv-tdot:first-child { background: #4A4D57; }
.rv-tname {
  margin-left: .4rem; font-family: var(--mono); font-size: .625rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--t-dim);
}

/* Every line keeps its space from the start, so nothing reflows as the log
   fills and the panel is only ever as tall as its six lines. */
.rv-log {
  list-style: none; margin: 0; padding: .7rem .7rem .75rem;
  display: grid; gap: .38rem;
}
.rv-log li {
  display: grid; grid-template-columns: .85rem minmax(0, max-content);
  gap: .4rem; align-items: baseline; justify-content: start;
  font-family: var(--mono); font-size: .6875rem; line-height: 1.35;
  color: var(--t-dim); opacity: 0; transition: opacity .3s;
  /* an empty row holds no content and would collapse, so the terminal would
     grow line by line and shove itself around. All six rows are reserved. */
  min-height: 1.35em;
}
.rv-log li.on { opacity: 1; }
.rv-log li.done, .rv-log li.p { color: var(--t-ink); }
.rv-log li.run { color: var(--t-acc); }
.rv-log .mk { justify-self: center; color: var(--t-acc); }
.rv-log li.p .mk:before { content: "$"; }
.rv-log .sp, .rv-log .ok { display: none; width: .68rem; height: .68rem; }
.rv-log li.busy .sp, .rv-log li.run .sp { display: block; animation: rvspin .85s linear infinite; }
.rv-log li.done .ok { display: block; }
.rv-log .sp { stroke: var(--t-acc); }
.rv-log .ok { stroke: var(--t-ok); }
@keyframes rvspin { to { transform: rotate(360deg); } }
/* the block cursor, on the line being typed and on the prompt while it waits */
.rv-log li.busy .tx:after, .rv-log li.waiting .tx:after {
  content: "\258C"; color: var(--t-acc); animation: rvblink 1s steps(1) infinite;
}
@keyframes rvblink { 50% { opacity: 0; } }

.rv-app {
  position: relative; border-radius: 10px; overflow: hidden; cursor: crosshair;
  /* dragging draws a stroke, so it must not select text or scroll the page */
  user-select: none; -webkit-user-select: none; touch-action: none;
  border: 1px solid var(--rule); background: var(--surface);
  box-shadow: 0 14px 34px -26px rgba(0, 0, 0, .5);
  opacity: 1; transform: none;
  transition: opacity .45s, transform .45s var(--ease),
              background .45s, border-color .45s, box-shadow .45s;
}
/* The interface arrives in two beats, tied to the two commands that produce
   it. On "list the controls" the window and its four labels appear and nothing
   else, because a list of controls is all the agent has at that point. On
   "build the interface" the boxes, the divider and the preview follow. Until
   the first of those the window is not there at all: an empty frame with
   nothing in it says less than plain panel does. */
/* not there yet means not clickable either, or an invisible window would take
   a click meant for the panel behind it and skip the build */
.rv-app.pending { opacity: 0; transform: translateY(8px) scale(.99); pointer-events: none; }
.rv-app.bare .rv-sw .box,
.rv-app.pending .rv-sw .box { opacity: 0; }
.rv-app.bare .rv-preview,
.rv-app.pending .rv-preview { opacity: 0; border-left-color: transparent; }
/* While the window is hidden its insides change state with no transition. The
   window fades in over .45s and the preview used to fade out over .4s at the
   same moment, so the preview showed through for a third of a second on its
   way out. Held at zero from the start, there is nothing to fade. */
.rv-app.pending .rv-sw .box,
.rv-app.pending .rv-preview { transition: none; }
.rv-bar { display: flex; align-items: center; gap: .45rem; padding: .45rem .7rem; border-bottom: 1px solid var(--rule); }
.rv-dot { width: .45rem; height: .45rem; border-radius: 50%; background: var(--acc); flex: none; }
.rv-ttl { font-family: var(--mono); font-size: .625rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.rv-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.rv-controls { padding: .5rem .8rem .6rem; display: grid; align-content: center; gap: .1rem; }
.rv-sw {
  display: flex; align-items: center; gap: .6rem; width: 100%; cursor: crosshair;
  background: none; border: 0; padding: .32rem .1rem; font: inherit; text-align: left;
  opacity: 1; transform: none; transition: opacity .3s, transform .3s var(--ease);
}
.rv-sw.pending { opacity: 0; transform: translateY(6px); }
.rv-sw .lbl { font-family: var(--ui); font-size: .875rem; color: var(--ink); }
.rv-sw .box {
  width: 1.1rem; height: 1.1rem; border-radius: 4px; flex: none; margin-left: auto;
  border: 1.5px solid var(--faint); display: grid; place-items: center;
  /* toggling stays instant; only the arrival fades */
  transition: opacity .32s, background .18s, border-color .18s;
}
.rv-sw[aria-checked="true"] .box { background: var(--acc); border-color: var(--acc); }
.rv-sw .box svg { width: .72rem; height: .72rem; opacity: 0; stroke: var(--on-acc); }
.rv-sw[aria-checked="true"] .box svg { opacity: 1; }
.rv-preview {
  border-left: 1px solid var(--rule); padding: .8rem 1rem;
  display: grid; align-content: center; justify-items: center; text-align: center;
  gap: .5rem; min-height: 8.5rem;
  opacity: 1; transition: opacity .4s, border-color .4s;
}
.rv-word { font-family: var(--display); font-weight: 400; font-size: 1.7rem; letter-spacing: -.02em; line-height: 1.1; }
.rv-word.b { font-weight: 700; }
.rv-word.i { font-style: italic; }
.rv-word.u { text-decoration: underline; text-underline-offset: .16em; text-decoration-thickness: from-font; }
.rv-word.g { font-size: 2.3rem; }
.rv-hint { font-family: var(--ui); font-size: .6875rem; line-height: 1.4; color: var(--muted); }
.rv-ink { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.rv-stroke { fill: none; stroke: var(--acc); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.rv-stroke.ghost { opacity: .5; }

/* The three columns hold as far down as they can by shrinking, because the row
   only reads as paper, work, result while all three are side by side. Below
   that the interface drops to its own line and the paper keeps the agent
   beside it, since a page and the record of what was read off it belong
   together. Last of all the paper moves above its own caption. */
@media (max-width: 1000px) {
  /* the longest log line is 19 monospace characters, so the agent column keeps
     10.75rem whatever else gives way, or every line wraps */
  .visual {
    grid-template-columns: minmax(0, 8.5rem) minmax(0, 10.75rem) minmax(0, 1fr);
    gap: clamp(.8rem, 1.8vw, 1.2rem);
  }
  .rv-paper { width: min(8.5rem, 100%); }
}
@media (max-width: 700px) {
  .visual { grid-template-columns: minmax(0, 9.5rem) minmax(0, 1fr); }
  .rv-app { grid-column: 1 / -1; }
  .page .rv-try { grid-column: 1 / -1; grid-row: auto; }
  .rv-cap { grid-column: 1 / -1; grid-row: auto; }
}
@media (max-width: 520px) {
  .visual { grid-template-columns: 1fr; row-gap: .9rem; }
  .rv-paper { width: min(11rem, 100%); justify-self: center; }
}
@media (max-width: 460px) {
  .rv-body { grid-template-columns: 1fr; }
  .rv-preview { border-left: 0; border-top: 1px solid var(--rule); min-height: 0; }
}

/* ---------- details ---------- */
.details { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); }
.details > div { padding: .8rem 1rem .8rem 0; }
.details > div + div { border-left: 1px solid var(--rule); padding-left: 1rem; }
.details .k { font-family: var(--ui); font-size: .6875rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); display: block; margin-bottom: .25rem; }
.details .v { font-family: var(--ui); font-size: .9375rem; font-weight: var(--w); display: block; }
.details .v small { display: block; font-weight: 400; color: var(--muted); font-size: .8125rem; margin-top: .1rem; }
@media (max-width: 780px) {
  .details { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .details > div:nth-child(3) { border-left: 0; padding-left: 0; }
  .details > div:nth-child(3), .details > div:nth-child(4) { border-top: 1px solid var(--rule); }
}
@media (max-width: 460px) { .details { grid-template-columns: 1fr; } .details > div + div { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule); } }

/* ---------- sections ---------- */
.sec { padding: clamp(2rem, 4.5vw, 3.2rem) 0; }
.sec.band { background: var(--band); }
.sec-head { max-width: 44rem; margin-bottom: 1.3rem; }
.sec-head .tag { font-family: var(--mono); font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: .5rem; }
.sec-head p { margin-top: .7rem; color: var(--muted); }

/* ---------- background ---------- */
/* the words on the left, the paper on the right, sized so the two columns come
   out close to the same height. Below 900px they stack instead, because a
   narrow right column leaves the paper stranded. */
.bg-top {
  display: grid; grid-template-columns: minmax(0,1fr) clamp(14rem, 34%, 21rem);
  gap: clamp(1.4rem, 4vw, 3rem); align-items: start;
}
@media (max-width: 900px) { .bg-top { grid-template-columns: 1fr; } }
.bg-facts { display: grid; gap: 1.2rem; align-content: start; }
.bg-facts .sec-head { margin-bottom: 0; max-width: 52ch; }
.paperthumb { display: grid; gap: .6rem; margin: 0; }
.sheetlink { display: block; border-radius: 3px; }
.sheetlink:hover .sheet { box-shadow: 0 10px 26px -14px rgba(0, 0, 0, .5); }
.paperthumb .sheet {
  display: block;
  aspect-ratio: 479 / 620;
  background: url(assets/paper/page1s.jpg) top center/cover no-repeat;
  border: 1px solid var(--rule); border-radius: 3px;
  box-shadow: 0 6px 18px -12px rgba(0,0,0,.4);
}
.paperthumb figcaption { font-family: var(--ui); font-size: .8125rem; line-height: 1.4; color: var(--muted); }
@media (max-width: 900px) { .paperthumb { max-width: 13rem; } }

.nums { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: .9rem 1.2rem; }
@media (max-width: 620px) { .nums { grid-template-columns: 1fr; gap: .6rem; } }
.nums div { border-top: 2px solid var(--acc); padding-top: .45rem; }
.nums b { display: block; font-family: var(--display); font-weight: var(--display-w); font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.5rem); letter-spacing: -.03em; line-height: 1; }
.nums span { display: block; font-family: var(--ui); font-size: .8125rem; line-height: 1.35; color: var(--muted); margin-top: .3rem; }
.caveat { font-size: .9375rem; line-height: 1.5; color: var(--muted); max-width: 62ch; }

.caveat b { font-weight: var(--w); color: var(--ink); }

.results {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(1.4rem, 3.5vw, 2.6rem); margin-top: 1.8rem;
  padding-top: 1.5rem; border-top: 1px solid var(--rule);
}
@media (max-width: 860px) { .results { grid-template-columns: 1fr; } }
.page .minihead { font-family: var(--mono); font-size: .625rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: .7rem; }
.wall { display: grid; gap: clamp(.3rem, .9vw, .62rem); }
.wrow { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr) 2.3rem; align-items: center; gap: .7rem; }
.page .wrow .nm { font-family: var(--ui); font-size: .8125rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
.page .wrow .nm:hover { color: var(--acc); }
.wrow .bar { height: .5rem; border-radius: 2px; background: var(--tint); overflow: hidden; }
.wrow .bar i { display: block; height: 100%; background: var(--ink); border-radius: 2px; }
.wrow .sc { font-family: var(--mono); font-size: .625rem; color: var(--muted); text-align: right; }
.page .wallnote { margin-top: .7rem; font-family: var(--ui); font-size: .75rem; line-height: 1.45; color: var(--muted); }
@media (max-width: 420px) {
  .wrow { grid-template-columns: 6.6rem minmax(0,1fr) 1.9rem; gap: .45rem; }
  .wrow .nm { font-size: .75rem; }
}

.cardrow { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: .9rem; }
@media (max-width: 460px) { .cardrow { grid-template-columns: 1fr; max-width: 17rem; } }
.card { min-width: 0; }
.cd { position: relative; width: 100%; aspect-ratio: 340 / 180; perspective: 900px; }
.cd-in { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .9s cubic-bezier(.45, 0, .2, 1); }
.cd.flip .cd-in { transform: rotateY(180deg); }
.cd-face {
  position: absolute; inset: 0; backface-visibility: hidden; border-radius: 5px;
  overflow: hidden; border: 1px solid var(--rule); background: var(--surface);
  box-shadow: 0 10px 24px -20px rgba(0, 0, 0, .55);
}
.cd-face.f img {
  width: 100%; height: 100%; display: block; object-fit: cover; object-position: center top;
  /* a touch of zoom trims the page margins, including the arXiv date stamp */
  transform: scale(1.12); transform-origin: center top;
}
.cd-face.b { transform: rotateY(180deg); background: var(--tint); }
.cd-face.b img { width: 100%; height: 100%; display: block; object-fit: cover; }
.cd-lbl {
  position: absolute; left: 0; right: 0; bottom: 0; padding: .3rem .5rem;
  font-family: var(--mono); font-size: .625rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink); text-align: center;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
}
.page .cardcap { margin-top: .5rem; font-family: var(--ui); font-size: .75rem; line-height: 1.4; color: var(--muted); }
.page .tools-head { margin-top: 1.8rem; }
.tools { display: grid; gap: .8rem; }
.trow { display: grid; grid-template-columns: 5.6rem minmax(0,1fr) 2.4rem; align-items: center; gap: .1rem .6rem; }
.trow .nm { font-family: var(--ui); font-size: .8125rem; white-space: nowrap; }
.trow .bar { height: .5rem; border-radius: 2px; background: var(--tint); overflow: hidden; }
.trow .bar i { display: block; height: 100%; background: var(--acc); border-radius: 2px; }
.trow .val { font-family: var(--mono); font-size: .6875rem; color: var(--muted); text-align: right; }
.trow .mdl { grid-column: 1 / -1; font-family: var(--mono); font-size: .625rem; color: var(--muted); }
.page .toolnote { margin-top: .6rem; font-family: var(--ui); font-size: .75rem; line-height: 1.45; color: var(--muted); }
.cardcap b { font-weight: var(--w); }
.page .cardcap a, .page .rv-cap a { color: var(--ink); }
.page .cardcap a:hover, .page .rv-cap a:hover { color: var(--acc); text-decoration: underline; }

/* ---------- program ---------- */
.prog { display: grid; }
.pl { position: relative; padding: .75rem 0; border-bottom: 1px solid var(--rule); }
.pl > .t { position: absolute; right: calc(100% + 1.5rem); top: .85rem; white-space: nowrap; font-family: var(--mono); font-size: .75rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.pl h3 { font-size: 1.0625rem; letter-spacing: -.01em; }
.pl .d { margin-top: .3rem; font-size: .9375rem; line-height: 1.5; color: var(--muted); max-width: 64ch; }
.pl.rest h3 { color: var(--muted); }
.pl.big { padding: 1.2rem 0 1.45rem; }
@media (max-width: 1180px) { .pl > .t { position: static; display: block; margin-bottom: .22rem; } }

/* the four beats of the live session, in the same icon language as the themes */
.steps { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 1rem 1.3rem; }
@media (max-width: 900px) { .steps { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } }
.steps li { display: grid; gap: .22rem; align-content: start; padding-top: .7rem; border-top: 1px solid var(--rule); }
.steps .n { font-family: var(--mono); font-size: .625rem; color: var(--muted); }
.steps .ic { width: 1.75rem; height: 1.75rem; color: var(--acc); margin: .1rem 0 .15rem; }
.steps .ic svg { width: 100%; height: 100%; display: block; }
.steps b { font-family: var(--ui); font-weight: var(--w); font-size: .9375rem; }
.steps .sd { font-size: .8125rem; line-height: 1.4; color: var(--muted); }

.themes3 { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 1.05rem 1.4rem; }
@media (max-width: 860px) { .themes3 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px) { .themes3 { grid-template-columns: 1fr; } }
.themes3 li { display: grid; gap: .22rem; align-content: start; }
.themes3 .ic { width: 1.75rem; height: 1.75rem; color: var(--acc); }
.themes3 .ic svg { width: 100%; height: 100%; display: block; }
.themes3 b { font-family: var(--ui); font-weight: var(--w); font-size: .9375rem; }
.themes3 span { font-size: .8125rem; line-height: 1.4; color: var(--muted); }

/* ---------- after the workshop ----------
   Each outcome is a drawing, a name and a line. The drawing is what gives the
   row its structure, which is why there is no rule above the name any more. */
.outs { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 1.6rem 1.7rem; }
@media (max-width: 760px) { .outs { grid-template-columns: 1fr; gap: 1.3rem; } }
/* the words carry the column and the drawing sits beside them, top-aligned, so
   the three names still read as a row across the section */
.outs > div { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .9rem; align-items: start; }
.outs .txt { display: grid; gap: .25rem; }
.outs .art { width: 5rem; height: 3.5rem; display: block; color: var(--faint); }
.outs b { font-family: var(--ui); font-weight: var(--w); font-size: .9375rem; }
.outs span { font-size: .8125rem; line-height: 1.45; color: var(--muted); }

/* ---------- registration, organizers, footer ---------- */
.prose { max-width: 64ch; display: grid; gap: .75rem; }
.prose b { font-weight: var(--w); }
.applyrow { margin-top: 1.5rem; }

/* twelve columns, so the three who lead the workshop fill the first row by
   themselves and everyone else follows four to a row, all styled the same */
.crew { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 1.1rem 1.2rem; }
.crew .p { grid-column: span 3; }
/* the fourth person opens a new row, which leaves the three who lead the
   workshop alone on the first one at exactly the same width and spacing */
.crew .p:nth-child(4) { grid-column: 1 / span 3; }
@media (max-width: 900px) { .crew { grid-template-columns: repeat(9, minmax(0, 1fr)); } }
@media (max-width: 620px) { .crew { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@media (max-width: 420px) { .crew { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.crew .p { display: flex; gap: .6rem; align-items: center; }
.crew .av { width: 2.6rem; height: 2.6rem; border-radius: 50%; background: var(--tint) center/cover no-repeat; color: var(--muted); display: grid; place-items: center; font-family: var(--ui); font-size: .75rem; flex: none; }
.crew .av.has-photo { color: transparent; }
.page .crew .nm { font-family: var(--ui); font-size: .9375rem; font-weight: var(--w); line-height: 1.25; display: block; color: var(--ink); }
.page .crew .nm:hover { color: var(--acc); text-decoration: underline; }
.crew .af { font-family: var(--ui); font-size: .8125rem; color: var(--muted); line-height: 1.3; display: block; }

footer { border-top: 1px solid var(--rule); }
.foot { max-width: 62rem; margin: 0 auto; padding: 1.5rem clamp(1rem, 4vw, 2rem) 1.3rem; font-family: var(--ui); font-size: .875rem; color: var(--muted); }
.page .foot .contact { margin: 0 0 1.1rem; }
.page .foot .contact a { color: var(--ink); }
.page .foot .contact a:hover { color: var(--acc); text-decoration: underline; }
.footmeta { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; align-items: center; padding-top: 1.1rem; border-top: 1px solid var(--rule); }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* the first paint of the field lands without a hundred flips at once */
.hf-grid.hf-instant .hf-flip { transition: none; }
