/* ==========================================================================
   SullyPC — bench violet
   Bone paper, plum ink, one violet, brass for prices and grades. Flat fills
   only. Type: Anton for the lockup, Hanken Grotesk headings, Albert Sans
   body, JetBrains Mono for labels, specs, and every numeral that matters.
   ========================================================================== */

/* The four faces, served from this domain. Latin subsets, cut to the weights
   the rules below ask for; licences and provenance in
   app/static/fonts/LICENSES.md. Three of the four are variable, so one file
   covers the whole range each one is declared with. */
@font-face {
  font-family: Anton;
  src: url(/static/fonts/anton-latin.woff2) format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url(/static/fonts/hanken-grotesk-latin.woff2) format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Albert Sans";
  src: url(/static/fonts/albert-sans-latin.woff2) format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url(/static/fonts/jetbrains-mono-latin.woff2) format("woff2");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --bone: #F2EFEA;
  --canvas: #E6E1DA;
  --ink: #1B1220;
  --plum: #2A1B3D;
  --violet: #6A3AB2;
  --violet-lt: #A170E9;
  --brass: #C98A2E;
  --brass-dk: #875C1F;
  --text: #3A3340;
  --text-soft: #564E5E;
  --muted: #625969;
  --muted-dk: #918899;
  --on-dark: #E4DEEA;
  --on-dark-soft: #B9B1C4;
  --on-dark-link: #D6CFE0;
  --hair: rgba(27,18,32,.16);
  --hair-lt: rgba(27,18,32,.14);
  --hair-md: rgba(27,18,32,.25);
  --hair-dk: rgba(242,239,234,.2);
  --f-anton: Anton, Impact, "Arial Narrow", sans-serif;
  --f-head: "Hanken Grotesk", Helvetica, Arial, sans-serif;
  --f-body: "Albert Sans", Helvetica, Arial, sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
  --wrap: 1240px;
  --gutter: 28px;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--bone); color: var(--text); font: 16px/1.5 var(--f-body); -webkit-font-smoothing: antialiased; overflow-x: clip; }
h1, h2, h3, p, ul, ol, dl, dd, figure, pre { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: var(--ink); text-decoration: none; }
a:hover { color: var(--violet); }
::selection { background: var(--violet); color: var(--bone); }
img { display: block; max-width: 100%; height: auto; }
button { font: inherit; }
.mono { font-family: var(--f-mono); font-feature-settings: "tnum"; }

/* Focus: one ring everywhere, lifted to the light violet on dark grounds. */
:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.panel-dark :focus-visible, .brief-band :focus-visible, .steps-band :focus-visible,
.hsheet :focus-visible, .menu-list :focus-visible { outline-color: var(--violet-lt); }
/* Radio, checkbox and the stage toggle hide their input, so the label wears
   the ring. */
label:has(input:focus-visible) { outline: 2px solid var(--violet); outline-offset: 2px; }
.brief-band label:has(input:focus-visible) { outline-color: var(--violet-lt); }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--gutter); top: -60px; z-index: 90;
  display: inline-flex; align-items: center; height: 40px; padding: 0 16px;
  background: var(--ink); color: var(--bone); font-family: var(--f-mono);
  font-size: 12px; letter-spacing: .04em;
}
.skip:focus { top: 10px; color: var(--bone); }
.wrap { max-width: var(--wrap); margin: 0 auto; padding-inline: var(--gutter); }

/* Lockup: SULLY solid ink, PC hollow violet. Stroke scales with size. */
.lockup { font-family: var(--f-anton); text-transform: uppercase; letter-spacing: .01em; line-height: 1; color: var(--ink); }
/* The exploded stage further down also draws boxes it calls .pc, so the two
   letters have to say they are letters: in flow, no border, no fill. */
.lockup .pc { position: static; border: 0; background: none; color: transparent; -webkit-text-stroke: 1.5px var(--violet); }
.lockup.on-dark { color: var(--bone); }
.lockup.on-dark .pc { -webkit-text-stroke-color: var(--bone); }

/* Type roles */
.h1 { font-family: var(--f-head); font-size: clamp(2.4rem, 1rem + 3.2vw, 3.8rem); font-weight: 600; letter-spacing: -0.05em; line-height: .88; color: var(--ink); text-wrap: pretty; }
.h2 { font-family: var(--f-head); font-size: clamp(2rem, 1rem + 2.2vw, 2.9rem); font-weight: 600; letter-spacing: -0.045em; line-height: .9; color: var(--ink); }
.h2.on-dark { color: var(--bone); font-weight: 500; letter-spacing: -0.035em; }
.h3 { font-family: var(--f-head); font-size: 20px; font-weight: 600; letter-spacing: -0.03em; line-height: 1.15; color: var(--ink); }
.lede { margin-top: 16px; max-width: 48ch; font-size: 17px; line-height: 1.5; }
.eyebrow { display: block; font-family: var(--f-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--violet); }
.eyebrow.muted { color: var(--muted); }
.eyebrow.on-dark { color: var(--violet-lt); }
.crumb { font-family: var(--f-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.crumb a { color: var(--muted); }
.kv { font-family: var(--f-mono); font-size: 12.5px; }
.kv li, .kv > div { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; border-top: 1px solid var(--hair); }
.kv li:last-child, .kv > div:last-child { border-bottom: 1px solid var(--hair); }
.kv .k { color: var(--muted); }
.kv .v { color: var(--ink); text-align: right; }

/* Buttons: flat rectangles, three kinds. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; height: 46px; padding: 0 24px; font-size: 15px; font-weight: 500; color: var(--bone); background: var(--violet); border: 1px solid var(--violet); cursor: pointer; white-space: nowrap; }
.btn:hover { color: var(--bone); background: #5A2F98; border-color: #5A2F98; }
.btn.line { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn.line:hover { background: var(--ink); color: var(--bone); }
.btn.small { height: 34px; padding: 0 16px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
.btn[disabled] { background: var(--muted-dk); border-color: var(--muted-dk); color: var(--ink); cursor: default; }
.link { color: var(--violet); border-bottom: 1px solid rgba(106,58,178,.4); }
.link.quiet { color: var(--muted); border-bottom-color: var(--hair); }
.chip { display: inline-block; padding: 4px 11px; border: 1px solid var(--ink); font-family: var(--f-mono); font-size: 11px; color: var(--ink); background: transparent; cursor: default; }
.chip.solid { background: var(--ink); color: var(--bone); }
.chip.faint { border-color: rgba(27,18,32,.3); color: var(--muted); }
.chip.on-dark { border-color: rgba(242,239,234,.5); color: var(--bone); }
.chip.pick { cursor: pointer; height: 31px; display: inline-flex; align-items: center; padding: 0 13px; letter-spacing: .04em; border-color: var(--hair-md); color: var(--text); }
.chip.pick.is-on { background: var(--ink); border-color: var(--ink); color: var(--bone); }
.price { font-family: var(--f-mono); color: var(--ink); }
.price.violet { color: var(--violet); }
.price.on-dark { color: var(--violet-lt); }
.panel-dark { background: var(--ink); color: var(--on-dark); }
.panel-dark a { color: var(--on-dark-link); }
.panel-dark a:hover { color: var(--bone); }
.log { font-family: var(--f-mono); font-size: 12.5px; line-height: 1.8; color: var(--on-dark); white-space: pre-wrap; }
.log-head { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; }
.log-head .file { font-family: var(--f-mono); font-size: 10px; color: var(--muted-dk); }
select, input[type=text], input[type=email], textarea { font: inherit; }

/* Header */
.site-header { position: relative; z-index: 70; background: var(--bone); border-bottom: 1px solid var(--hair-lt); }
.header-row { height: 62px; display: flex; align-items: center; gap: 26px; }
.header-row .lockup { font-size: 25px; }
.hnav { display: flex; align-items: center; gap: 2px; font-size: 14px; }
.hnav > a, .hnav .menu > a { display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px; color: var(--text); border-bottom: 2px solid transparent; }
.hnav > a.is-on, .hnav .menu > a.is-on { color: var(--ink); border-bottom-color: var(--violet); }
.hnav .menu > a { padding-right: 4px; }
/* The caret is its own button so the drop-down opens from the keyboard. */
.hnav .caret { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; padding: 0 8px 0 2px; border: 0; border-bottom: 2px solid transparent; background: transparent; font-size: 9px; color: var(--violet); cursor: pointer; }
.hnav .menu > a.is-on + .caret { border-bottom-color: var(--violet); }
.hnav .menu { position: relative; display: inline-flex; align-items: stretch; }
.hnav .menu-list { display: none; position: absolute; left: 0; top: 100%; min-width: 250px; padding: 8px; background: var(--ink); box-shadow: 0 18px 40px rgba(27,18,32,.3); flex-direction: column; }
.hnav .menu.is-open .menu-list { display: flex; }
.hnav .menu-list a { padding: 10px 12px; font-size: 14px; color: var(--on-dark-link); }
.hnav .menu-list a:first-child { color: var(--bone); }
.hnav .menu-list a:hover { background: var(--plum); color: var(--bone); }
.hnav .menu-list .lbl { padding: 13px 12px 5px; font-family: var(--f-mono); font-size: 10px; letter-spacing: .12em; color: var(--muted-dk); }
.hactions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.burger { display: none; align-items: center; justify-content: center; width: 38px; height: 36px; border: 1px solid rgba(27,18,32,.22); background: transparent; color: var(--ink); font-size: 15px; cursor: pointer; }
.tray-link { display: flex; align-items: center; gap: 9px; height: 36px; padding: 0 15px; border: 1px solid rgba(27,18,32,.22); font-family: var(--f-mono); font-size: 12px; color: var(--ink); }
.tray-link b { display: inline-grid; place-items: center; min-width: 19px; height: 19px; padding: 0 5px; background: var(--violet); color: var(--bone); font-size: 11px; font-weight: 500; }
.talk { display: flex; align-items: center; height: 36px; padding: 0 17px; background: var(--ink); color: var(--bone); font-size: 13px; font-weight: 500; }
.talk:hover { background: var(--plum); color: var(--bone); }
.hsheet { display: none; border-top: 1px solid var(--hair-lt); background: var(--ink); padding: 18px var(--gutter) 22px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 22px; }
.hsheet.is-open { display: grid; }
.hsheet div { display: flex; flex-direction: column; gap: 8px; }
.hsheet .lbl { font-family: var(--f-mono); font-size: 10px; letter-spacing: .12em; color: var(--violet-lt); }
.hsheet a { font-size: 14.5px; color: var(--on-dark-link); }
.hsheet a:first-of-type { color: var(--bone); }
.notice { background: var(--canvas); border-bottom: 1px solid var(--hair-lt); padding: 8px var(--gutter); text-align: center; font-size: 13px; color: var(--ink); }

/* Footer */
.site-footer { background: var(--bone); border-top: 1px solid var(--hair-lt); padding: 44px 0 40px; }
.footer-row { display: flex; flex-wrap: wrap; gap: 28px; align-items: flex-end; justify-content: space-between; }
.footer-row .lockup { font-size: 25px; }
.footer-row .origin { display: block; margin-top: 12px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .13em; color: var(--text); }
.footer-row nav { display: flex; flex-wrap: wrap; gap: 22px; font-size: 14px; }
.footer-row nav a { color: var(--text); }
.footer-row .legal { font-family: var(--f-mono); font-size: 11px; color: var(--muted); }

/* ------------------------------------------------------------------ Home */

/* Stage: the case comes apart as you scroll. Scroll-driven animation
   where supported, with a checkbox that forces the blown state anywhere. */
.stage { position: relative; height: 260vh; background: var(--bone); view-timeline-name: --explode; view-timeline-axis: block; }
.stage-pin { position: sticky; top: 0; height: calc(100dvh - 62px); overflow: clip; display: flex; flex-direction: column; align-items: center; padding: 18px var(--gutter) 14px; }
.stage-head { flex: none; width: 100%; text-align: center; }
.stage-head .lockup { display: block; font-size: clamp(3rem, 1rem + 7.4vw, 8rem); line-height: .84; }
.stage-head .lockup .pc { -webkit-text-stroke-width: 4px; }
.stage-head .origin { display: block; margin-top: 9px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .13em; color: var(--violet); }
.stage-head .copy-a, .stage-head .copy-b { display: block; margin-top: 9px; font-family: var(--f-head); font-size: clamp(1.05rem, 1rem + .8vw, 1.5rem); font-weight: 500; letter-spacing: -0.03em; line-height: 1.15; color: var(--text); }
.stage-head .copy-b { margin-top: -1.15em; opacity: 0; }
.stage-art-wrap { flex: 1 1 auto; min-height: 0; width: 100%; display: grid; place-items: center; }
.art { position: relative; width: min(900px, 62%, 56vh); aspect-ratio: 900 / 560; container-type: inline-size; }
.pc { position: absolute; border: 2px solid var(--ink); background: var(--bone); }
.pc.frame { left: 6.67cqw; top: 3.33cqw; width: 57.78cqw; height: 55.56cqw; background: transparent; border-color: rgba(27,18,32,.55); --tx: -2.8cqw; --ty: .7cqw; --rot: -1deg; --sc: 1.02; }
.pc.board { left: 10.67cqw; top: 10.67cqw; width: 33.33cqw; height: 36.67cqw; border-color: var(--violet); background: transparent; --tx: -11.9cqw; --ty: 1.8cqw; --rot: -3deg; }
.pc.cpu { left: 13.1cqw; top: 13.1cqw; width: 10.2cqw; height: 10.2cqw; --tx: -25.3cqw; --ty: -4cqw; --rot: -6deg; }
.pc.ram1 { left: 27.3cqw; top: 13.1cqw; width: 1.6cqw; height: 16.4cqw; border-color: var(--brass); --tx: -10.5cqw; --ty: -7.3cqw; --rot: 4deg; }
.pc.ram2 { left: 30.2cqw; top: 13.1cqw; width: 1.6cqw; height: 16.4cqw; border-color: var(--brass); --tx: -4.8cqw; --ty: -8.2cqw; --rot: 6deg; }
.pc.gpu { left: 11.6cqw; top: 33.3cqw; width: 37.8cqw; height: 8cqw; --tx: -1.5cqw; --ty: 6.6cqw; --rot: 3deg; }
.pc.psu { left: 10.67cqw; top: 45.8cqw; width: 22.2cqw; height: 10.7cqw; border-color: rgba(27,18,32,.7); --tx: -21.4cqw; --ty: 4.7cqw; --rot: -4deg; }
.pc.nvme { left: 47.8cqw; top: 12.4cqw; width: 14.4cqw; height: 6.4cqw; border-color: var(--violet); --tx: 25.3cqw; --ty: -4.9cqw; --rot: 5deg; }
.pc.hdd { left: 47.8cqw; top: 23.3cqw; width: 16.7cqw; height: 10.2cqw; border-color: rgba(27,18,32,.7); --tx: 29.3cqw; --ty: -1.1cqw; --rot: 3deg; }
.pc.fan1 { left: 52.2cqw; top: 41.3cqw; width: 8.7cqw; height: 8.7cqw; background: transparent; border-color: rgba(106,58,178,.75); --tx: 27.3cqw; --ty: 4.1cqw; --rot: -8deg; }
.pc.fan2 { left: 52.2cqw; top: 41.3cqw; width: 8.7cqw; height: 8.7cqw; background: transparent; border-color: rgba(106,58,178,.55); --tx: 37.1cqw; --ty: 6.9cqw; --rot: 10deg; }
.pc.glass { left: 6.67cqw; top: 3.33cqw; width: 57.78cqw; height: 55.56cqw; border-color: rgba(27,18,32,.25); background: rgba(106,58,178,.06); --tx: 6.3cqw; --ty: -2.5cqw; --rot: 2deg; --sc: 1.12; }
.pc i { position: absolute; display: block; border: 2px solid; }
.pc-shift { position: absolute; inset: 0; transform: translateX(14.4cqw); }
.pc-label { position: absolute; font-family: var(--f-mono); font-size: clamp(11px, 1.9cqw, 15px); font-weight: 500; color: var(--muted); opacity: 0; }
.pc-key { flex: none; width: 100%; max-width: 1000px; margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px 20px; justify-content: center; font-family: var(--f-mono); font-size: 12.5px; color: var(--text); opacity: 0; }
.pc-key b { color: var(--violet); font-weight: 500; }
.stage-foot { flex: none; width: 100%; display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; align-items: center; }
.stage-foot .hint { font-family: var(--f-mono); font-size: 11px; color: var(--muted); }
.stage-foot label { display: flex; align-items: center; height: 34px; padding: 0 14px; border: 1px solid var(--hair-md); font-family: var(--f-mono); font-size: 11px; color: var(--ink); cursor: pointer; user-select: none; }
.stage-foot label input { position: absolute; opacity: 0; width: 0; height: 0; }
.lbl-on { display: none; }
@keyframes explode { to { transform: translate(var(--tx, 0), var(--ty, 0)) rotate(var(--rot, 0deg)) scale(var(--sc, 1)); } }
@keyframes fadeUpIn { 0%, 34% { opacity: 0; } 100% { opacity: 1; } }
@keyframes fadeOutEarly { 0% { opacity: 1; } 42%, 100% { opacity: 0; } }
@supports (animation-timeline: --x) {
  .pc, .pc-label, .pc-key, .copy-a, .copy-b { animation-duration: 1s; animation-timing-function: linear; animation-fill-mode: both; animation-timeline: --explode; animation-range: cover 28% cover 70%; }
  .pc { animation-name: explode; }
  .pc-label, .pc-key, .copy-b { animation-name: fadeUpIn; }
  .pc.glass, .copy-a { animation-name: fadeOutEarly; }
}
/* Forced state: the checkbox, or a browser without scroll timelines after JS marks it. */
.stage.is-blown .pc, .stage:has(.blow:checked) .pc { animation: none; transform: translate(var(--tx, 0), var(--ty, 0)) rotate(var(--rot, 0deg)) scale(var(--sc, 1)); }
.stage.is-blown .pc-shift, .stage:has(.blow:checked) .pc-shift { transform: none; }
.stage.is-blown :is(.pc-label, .pc-key, .copy-b), .stage:has(.blow:checked) :is(.pc-label, .pc-key, .copy-b) { animation: none; opacity: 1; }
.stage.is-blown :is(.pc.glass, .copy-a), .stage:has(.blow:checked) :is(.pc.glass, .copy-a) { animation: none; opacity: 0; }
.stage.is-blown .lbl-off, .stage:has(.blow:checked) .lbl-off { display: none; }
.stage.is-blown .lbl-on, .stage:has(.blow:checked) .lbl-on { display: inline; }
@media (max-width: 900px) {
  .hnav { display: none; }
  .burger { display: inline-flex; }
  .talk { display: none; }
  .stage { height: auto; }
  .stage-pin { position: static; height: auto; }
  .art { width: min(560px, 100%); }
  /* No tall scroll area at this width, so the scroll timeline would leave the
     labels stuck half faded. The toggle does the whole job here. */
  .pc, .pc-label, .pc-key, .copy-a, .copy-b { animation: none; }
  .stage-foot .hint { display: none; }
}
/* Narrow enough that the drawing fills the column, so the pieces that fly left
   would land off the screen. Shrink the whole drawing instead of moving them,
   and pull the height the shrinking freed back out so the section keeps its
   spacing. The -6.84% is half of the height it loses: 0.6222 (the aspect) times
   the 0.22 it gives up, against the column width a vertical margin measures. */
@media (max-width: 800px) {
  .art { width: 100%; transform: scale(.78); margin-block: -6.84%; }
}

.hero-band { border-bottom: 1px solid var(--hair-lt); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .92fr); gap: 56px; align-items: end; }
.hero-copy { padding: 78px 0 62px; }
.hero-copy .live { display: inline-flex; align-items: center; gap: 9px; }
.hero-copy .live i { width: 7px; height: 7px; background: var(--violet); animation: blink 1.6s steps(1) infinite; }
@keyframes blink { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
.hero-copy .h1 { margin-top: 18px; font-size: clamp(2.9rem, 1rem + 4.6vw, 4.6rem); line-height: .86; }
.hero-copy .lede { margin-top: 22px; max-width: 46ch; font-size: 18px; line-height: 1.45; }
.cta-row { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 11px; }
.stats { margin-top: 44px; display: flex; flex-wrap: wrap; gap: 34px; }
.stats dt { font-family: var(--f-mono); font-size: 11px; letter-spacing: .1em; color: var(--muted); }
.stats dd { margin-top: 5px; font-family: var(--f-mono); font-size: 25px; color: var(--ink); }
.hero-fig { position: relative; align-self: stretch; display: flex; align-items: flex-end; }
.hero-fig img { width: 100%; height: 520px; object-fit: cover; object-position: 50% 45%; background: var(--canvas); }
.hero-fig figcaption { position: absolute; left: 0; right: 0; bottom: 0; padding: 13px 16px; background: var(--ink); display: flex; justify-content: space-between; gap: 14px; align-items: baseline; font-family: var(--f-mono); font-size: 11px; color: var(--on-dark-link); }
.hero-fig figcaption b { font-weight: 400; color: var(--violet-lt); }
.ticker { border-top: 1px solid var(--hair-lt); background: var(--canvas); overflow: hidden; display: flex; align-items: center; }
.ticker .tag { flex: none; padding: 11px 18px; background: var(--ink); color: var(--bone); font-family: var(--f-mono); font-size: 11px; letter-spacing: .12em; }
.ticker .lane { flex: 1; overflow: hidden; white-space: nowrap; }
.ticker .drift { display: inline-flex; animation: drift 46s linear infinite; }
.ticker .drift span { padding: 0 22px; font-family: var(--f-mono); font-size: 12px; color: var(--text); }
.ticker-stop { flex: none; height: 26px; margin: 0 14px; padding: 0 12px; border: 1px solid var(--hair-md); background: transparent; font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em; color: var(--ink); cursor: pointer; }
.ticker-stop:hover { border-color: var(--ink); }
.ticker.is-paused .drift { animation-play-state: paused; }
@keyframes drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (hover: hover) { .ticker:hover .drift { animation-play-state: paused; } }

.section { padding-top: 72px; }
.section-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 20px; }
.three { margin-top: 26px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.card { display: block; padding: 22px 24px 24px; background: var(--canvas); }
.card:hover { color: inherit; }
.card .top { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.card .cat { font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.card .h3 { margin-top: 12px; }
.card p { margin-top: 8px; font-size: 14.5px; line-height: 1.45; color: var(--text-soft); }
.card .price { display: block; margin-top: 16px; font-size: 18px; }
.card.dark { background: var(--ink); }
.card.dark .cat { color: var(--violet-lt); } .card.dark .h3 { color: var(--bone); } .card.dark p { color: var(--on-dark-soft); }
.two { display: grid; grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); gap: 52px; align-items: start; }
.steps-mini { margin-top: 24px; display: flex; flex-direction: column; gap: 14px; }
.steps-mini li { display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 14px; font-size: 15.5px; line-height: 1.45; }
.steps-mini .n { font-family: var(--f-mono); font-size: 12px; color: var(--violet); padding-top: 3px; }
.steps-mini b { color: var(--ink); font-weight: 600; }
.log-panel { background: var(--ink); padding: 24px 26px 26px; }
.log-panel .log { margin-top: 14px; }
.log-panel p { margin-top: 14px; font-size: 14px; line-height: 1.5; color: var(--on-dark-soft); }
.band { margin-top: 80px; background: var(--canvas); border-top: 1px solid var(--hair-lt); border-bottom: 1px solid var(--hair-lt); padding: 68px 0 72px; }
.band .two { grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.band img { width: 100%; height: 340px; object-fit: cover; background: var(--canvas); }
.pair { padding-block: 72px 84px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.pair .card { padding: 26px 28px 28px; }
.pair .card.line { background: transparent; border: 1px solid rgba(27,18,32,.2); }
.pair .card .h3 { font-size: 24px; margin-top: 10px; }
.pair .card p { font-size: 15.5px; line-height: 1.5; max-width: 44ch; }
.pair .card .more { display: block; margin-top: 16px; font-size: 15px; color: var(--violet); }
.pair .card.dark .more { color: var(--violet-lt); }

/* ------------------------------------------------------------------ Parts */
.page-top { padding-top: 46px; }
.page-top.roomy { padding-top: 56px; }
.intro { margin-top: 22px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .7fr); gap: 48px; align-items: end; }
.intro .lede { max-width: 54ch; }
.filters { margin-top: 34px; display: flex; flex-wrap: wrap; gap: 18px 32px; align-items: center; padding-bottom: 15px; border-bottom: 2px solid var(--ink); }
.filters .chips { display: flex; flex-wrap: wrap; gap: 7px; }
.filters label { display: flex; align-items: center; gap: 9px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .08em; color: var(--muted); }
.filters select { height: 31px; padding: 0 9px; border: 1px solid var(--hair-md); background: var(--bone); font-family: var(--f-mono); font-size: 11.5px; color: var(--ink); }
.filters .shown { margin-left: auto; font-family: var(--f-mono); font-size: 12px; color: var(--muted); }
.rows li { border-bottom: 1px solid var(--hair); }
.rows li.is-open { background: var(--canvas); }
.rows li.is-held .row-name, .rows li.is-held .price { color: var(--muted); }
/* The row is the button that opens the log under it. */
.row { display: grid; grid-template-columns: 124px minmax(0, 1fr) 132px 122px; gap: 18px; align-items: start; width: 100%; padding: 20px 4px 19px; border: 0; background: transparent; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.row .row-main, .row .right { display: block; }
.row .cat { font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding-top: 5px; }
.row-name { display: block; font-family: var(--f-head); font-size: 21px; font-weight: 600; letter-spacing: -0.025em; line-height: 1.12; color: var(--ink); }
.row .blurb { display: block; margin-top: 6px; max-width: 62ch; font-size: 14.5px; line-height: 1.45; color: var(--text-soft); }
.row .chip { justify-self: start; }
.row .right { text-align: right; }
.row .price { display: block; font-size: 17px; }
.row .hint { display: block; margin-top: 7px; font-family: var(--f-mono); font-size: 11px; color: var(--violet); }
.detail { display: none; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 26px; padding: 4px 4px 30px; }
li.is-open .detail { display: grid; }
.detail .log-panel { padding: 20px 22px; }
.detail .log { font-size: 12px; line-height: 1.75; margin-top: 12px; }
.detail .note { margin-top: 16px; font-size: 14.5px; line-height: 1.5; color: var(--text-soft); }
.detail .acts { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.set-aside { height: 42px; padding: 0 20px; border: 1px solid var(--ink); background: var(--ink); color: var(--bone); font-size: 14px; font-weight: 500; cursor: pointer; }
.set-aside.is-in { background: transparent; color: var(--ink); }
.set-aside.wide { width: 100%; height: 50px; font-size: 15px; }
.set-aside[disabled] { background: transparent; border-color: var(--hair-md); color: var(--muted); cursor: default; }
.rows-note { margin-top: 20px; padding-bottom: 72px; font-size: 14.5px; color: var(--text-soft); }

/* ------------------------------------------------------------------ Part */
.part-grid { margin-top: 26px; display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 56px; align-items: start; }
.shots { position: relative; height: 470px; background: var(--canvas); border: 1px solid var(--hair); }
.shots img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity .35s ease; opacity: 0; }
.shots img.is-on { opacity: 1; }
.shots .cap { position: absolute; left: 14px; bottom: 14px; padding: 6px 11px; background: var(--ink); color: var(--bone); font-family: var(--f-mono); font-size: 11px; }
.thumbs { margin-top: 10px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; max-width: 560px; }
.thumbs button { padding: 0; border: 2px solid var(--hair); background: transparent; cursor: pointer; line-height: 0; }
.thumbs button.is-on { border-color: var(--violet); }
.thumbs img { width: 100%; height: 80px; object-fit: cover; opacity: .55; }
.thumbs button.is-on img { opacity: 1; }
.tabs { margin-top: 40px; display: flex; flex-wrap: wrap; gap: 8px; }
.tabs button { height: 38px; padding: 0 16px; border: 1px solid var(--hair-md); background: transparent; color: var(--text); font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .05em; cursor: pointer; }
.tabs button.is-on { background: var(--ink); border-color: var(--ink); color: var(--bone); }
.tab-pane { display: none; margin-top: 16px; }
.tab-pane.is-on { display: block; }
.tab-pane .log-panel { padding: 22px 24px; }
.marks { display: flex; flex-direction: column; gap: 12px; }
.marks li { display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 16px; padding: 14px 16px; background: var(--canvas); font-size: 14.5px; line-height: 1.45; }
.marks .n { font-family: var(--f-mono); font-size: 11px; color: var(--violet); }
.buy .h1 { margin-top: 10px; font-size: clamp(1.9rem, 1rem + 1.8vw, 2.6rem); line-height: .95; letter-spacing: -0.04em; }
.buy .meta { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; font-family: var(--f-mono); font-size: 11.5px; color: var(--muted); }
.buy .price { display: block; margin-top: 22px; font-size: 34px; }
.buy .set-aside { margin-top: 22px; }
.buy .tray-note { display: block; margin-top: 10px; padding-block: 3px; text-align: center; font-size: 14px; color: var(--violet); }
.buy .story { margin-top: 24px; font-size: 16px; line-height: 1.5; }
.buy .kv { margin-top: 20px; }

/* ------------------------------------------------------------------ Builds */
.builds-top { margin-top: 26px; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 52px; align-items: start; }
.builds-top .kv { margin-top: 26px; font-size: 13px; }
.builds-top .btn { margin-top: 26px; }
.angles { position: relative; height: 440px; background: var(--canvas); border: 1px solid var(--hair); }
.angles img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity .45s ease; opacity: 0; }
.angles img.is-on { opacity: 1; }
.angles .cap { position: absolute; left: 14px; bottom: 14px; padding: 6px 11px; background: var(--ink); color: var(--bone); font-family: var(--f-mono); font-size: 11px; }
.angle-hint { margin-top: 12px; font-family: var(--f-mono); font-size: 11px; color: var(--muted); }
.angle-pause { min-height: 24px; margin-left: 10px; padding: 0 9px; border: 1px solid var(--hair-md); background: transparent; font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em; color: var(--ink); cursor: pointer; }
.angle-pause:hover { border-color: var(--ink); }
.work-band { margin-top: 76px; background: var(--canvas); border-top: 1px solid var(--hair-lt); border-bottom: 1px solid var(--hair-lt); padding: 66px 0 72px; }
.work-band .section-head p { max-width: 42ch; font-size: 16px; line-height: 1.45; }
.strip { margin-top: 30px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 12px; }
.strip::-webkit-scrollbar { height: 6px; } .strip::-webkit-scrollbar-thumb { background: var(--hair-md); }
.strip-track { display: flex; gap: 20px; padding: 0 var(--gutter); width: max-content; }
.wcard { flex: none; width: 360px; scroll-snap-align: start; background: var(--bone); border: 1px solid var(--hair); }
.wcard img { width: 100%; height: 220px; object-fit: cover; background: var(--canvas); }
/* The tight tier. A card in a strip is read at a glance, so it is packed;
   the standard tier is the 24px of .card and .step-out, and the roomy tier
   is .summary, where someone is filling a form in. */
.wcard .body { padding: 14px 16px 16px; }
.wcard .h3 { margin-top: 8px; }
.wcard p { margin-top: 8px; font-size: 14.5px; line-height: 1.45; color: var(--text-soft); }
.wcard .kv { margin-top: 14px; font-size: 12px; }
.wcard .kv li { padding: 7px 0; border-color: var(--hair-lt); }
.wcard .kv li:last-child { border-bottom: 0; }
.brief-band { background: var(--ink); color: var(--on-dark); padding: 80px 0 88px; }
.brief-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 60px; align-items: start; }
.brief-band .lede { color: var(--on-dark-soft); font-size: 16px; }
.q { margin-top: 30px; }
.q:first-of-type { margin-top: 34px; }
.q .choices { margin-top: 12px; display: flex; flex-wrap: wrap; gap: 8px; }
.q .choices label { display: inline-flex; align-items: center; height: 40px; padding: 0 16px; border: 1px solid var(--hair-dk); color: var(--on-dark-link); font-size: 14px; cursor: pointer; }
.q .choices input { position: absolute; opacity: 0; width: 0; height: 0; }
.q .choices label:has(input:checked) { background: var(--violet); border-color: var(--violet); color: var(--bone); }
.q .choices.pri label { height: 36px; padding: 0 14px; font-family: var(--f-mono); font-size: 12px; }
.q .choices.pri label:has(input:checked) { background: var(--brass); border-color: var(--brass); color: var(--ink); }
.q .range { margin-top: 14px; display: flex; align-items: center; gap: 20px; }
.q .range input { flex: 1; min-width: 160px; accent-color: var(--violet); }
.q .range output { font-family: var(--f-mono); font-size: 24px; color: var(--bone); min-width: 108px; text-align: right; }
.who { margin-top: 32px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; max-width: 520px; }
.who label { display: grid; gap: 7px; font-family: var(--f-mono); font-size: 10px; letter-spacing: .1em; color: var(--muted-dk); }
.who input { height: 42px; padding: 0 12px; border: 1px solid var(--hair-dk); background: var(--plum); color: var(--bone); font-size: 15px; }
.brief-band .btn { margin-top: 18px; height: 48px; padding: 0 26px; border: 0; }
.ticket { background: var(--bone); color: var(--ink); }
.ticket .head { padding: 16px 20px; background: var(--violet); display: flex; justify-content: space-between; align-items: baseline; gap: 14px; }
.ticket .head .lockup { font-size: 22px; color: var(--bone); }
.ticket .head .lockup .pc { -webkit-text-stroke-color: var(--bone); }
.ticket .head .lbl { font-family: var(--f-mono); font-size: 10px; letter-spacing: .12em; color: var(--on-dark); }
.ticket .body { padding: 20px; }
.ticket .kv > div { border-top: 0; border-bottom: 1px solid var(--hair); padding: 10px 0; }
.ticket .kv > div:last-child { border-bottom: 0; }
.ticket .v.brass { color: var(--brass-dk); }
.ticket p { margin-top: 16px; font-size: 14px; line-height: 1.5; color: var(--text-soft); }

/* ------------------------------------------------------------------ About */
.about-top { margin-top: 26px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .72fr); gap: 52px; align-items: end; }
.about-top p { font-size: 17px; line-height: 1.5; }
.steps-band { margin-top: 52px; background: var(--ink); color: var(--on-dark); padding: 64px 0 72px; }
.steps-grid { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: 40px; align-items: start; }
.step { display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 16px; padding: 14px 16px; cursor: pointer; }
.step.is-on { background: var(--plum); }
/* The step that is open says so with a filled numeral, not a coloured rail. */
.step .n { justify-self: start; align-self: start; margin-top: 2px; padding: 3px 7px; font-family: var(--f-mono); font-size: 12px; color: var(--muted-dk); }
.step.is-on .n { background: var(--violet); color: var(--bone); }
.step b { display: block; font-family: var(--f-head); font-size: 19px; font-weight: 500; letter-spacing: -0.02em; color: var(--on-dark-link); }
.step.is-on b { color: var(--bone); }
.step span { display: block; margin-top: 4px; font-size: 14px; line-height: 1.45; color: var(--muted-dk); }
.step.is-on span { color: var(--on-dark-link); }
.step-out { background: var(--plum); padding: 22px 24px 24px; }
.step-out .log { margin-top: 14px; }
.step-out .pane { display: none; } .step-out .pane.is-on { display: block; }
.grades { margin-top: 22px; }
.grades .lbl { display: block; font-family: var(--f-mono); font-size: 10px; letter-spacing: .12em; color: var(--muted-dk); }
.grades ul { margin-top: 12px; }
.grades li { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 18px; align-items: baseline; padding: 11px 13px; }
.grades li.is-on { background: var(--bone); }
.grades b { font-family: var(--f-head); font-size: 17px; font-weight: 500; letter-spacing: -0.02em; color: var(--on-dark-link); }
.grades li.is-on b { color: var(--ink); }
.grades span { font-size: 13.5px; line-height: 1.4; color: var(--muted-dk); }
.grades li.is-on span { color: var(--text-soft); }
.who-grid { padding-block: 76px 84px; display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 60px; align-items: start; }
.who-grid p { margin-top: 24px; max-width: 58ch; font-size: 19px; line-height: 1.45; }
.who-grid p + p { margin-top: 18px; }
.who-grid p b { color: var(--ink); font-weight: 600; }
.facts { position: sticky; top: 28px; background: var(--bone); border: 1px solid rgba(27,18,32,.2); padding: 18px 20px 20px; }
.facts .lbl { display: block; font-family: var(--f-mono); font-size: 10px; letter-spacing: .1em; color: var(--muted); }
.facts dl { margin-top: 14px; display: grid; grid-template-columns: 84px minmax(0, 1fr); row-gap: 10px; column-gap: 12px; font-family: var(--f-mono); font-size: 12.5px; }
.facts dt { color: var(--muted); } .facts dd { color: var(--ink); }
.facts .tools { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--hair); }
.facts .tools ul { margin-top: 9px; display: flex; flex-direction: column; gap: 5px; font-family: var(--f-mono); font-size: 12px; color: var(--ink); }

/* ------------------------------------------------------------------ Tray */
.tray-grid { margin-top: 38px; display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 48px; align-items: start; }
.tray-empty { padding: 34px 32px; background: var(--canvas); }
.tray-empty b { display: block; font-family: var(--f-head); font-size: 22px; font-weight: 600; letter-spacing: -0.03em; color: var(--ink); }
.tray-empty p { margin-top: 10px; max-width: 46ch; font-size: 15.5px; line-height: 1.5; color: var(--text-soft); }
.tray-empty .btn { margin-top: 20px; height: 44px; }
.tray-line { display: grid; grid-template-columns: 116px minmax(0, 1fr) auto; gap: 20px; align-items: center; padding: 18px 0; border-top: 1px solid var(--hair); }
.tray-line .cat { font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.tray-line b { display: block; font-family: var(--f-head); font-size: 19px; font-weight: 600; letter-spacing: -0.025em; color: var(--ink); }
.tray-line .grade { display: block; margin-top: 4px; font-family: var(--f-mono); font-size: 11.5px; color: var(--violet); }
.tray-line .remove { margin-top: 7px; min-height: 24px; border: 0; background: transparent; padding: 0; font-size: 13px; color: var(--muted); border-bottom: 1px solid var(--hair); cursor: pointer; }
.tray-line .price { font-size: 16px; }
.tray-promise { margin-top: 26px; padding: 20px 22px; }
.tray-promise ul { margin-top: 12px; display: flex; flex-direction: column; gap: 7px; font-size: 14px; line-height: 1.45; }
.summary { background: var(--canvas); padding: 30px 30px 32px; }
.summary .lbl { display: block; font-family: var(--f-mono); font-size: 10px; letter-spacing: .1em; color: var(--muted); }
.summary .kv { margin-top: 14px; }
.summary .kv > div { border-top: 1px solid rgba(27,18,32,.18); }
.summary .kv > div:last-child { border-bottom: 0; border-top: 2px solid var(--ink); padding-top: 12px; margin-top: 4px; }
.summary .kv > div:last-child .k { color: var(--ink); font-size: 14px; }
.summary .kv > div:last-child .v { font-size: 18px; }
.summary form { margin-top: 18px; }
.summary label { display: grid; gap: 6px; font-family: var(--f-mono); font-size: 10px; letter-spacing: .1em; color: var(--muted); }
.summary input, .summary textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--hair-md); background: var(--bone); color: var(--ink); font-size: 15px; }
.summary label + label { margin-top: 10px; }
.summary .btn { margin-top: 14px; width: 100%; height: 48px; border: 0; }
.summary .note { margin-top: 12px; font-size: 13px; line-height: 1.5; color: var(--text-soft); }
.summary .local { margin-top: 18px; padding-top: 14px; border-top: 1px solid rgba(27,18,32,.18); }
.summary .local p { margin-top: 8px; font-size: 13.5px; line-height: 1.5; }

/* Small pages */
.plain { padding-block: 46px 96px; }
.plain .h1 { margin-top: 22px; }
.plain p { margin-top: 18px; max-width: 54ch; font-size: 17px; line-height: 1.5; }
.plain .btn { margin-top: 26px; }

/* ------------------------------------------------------------------ Responsive */
/* The 980px block sits at the foot of the file, after the row photo whose
   width it narrows. */
@media (max-width: 760px) {
  :root { --gutter: 20px; }
  .pair, .who { grid-template-columns: minmax(0, 1fr); }
  .grades li { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .stats { gap: 22px; }
  .thumbs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Nothing drifts, so the lane scrolls by hand and the second, duplicated
     set of items comes out. */
  .ticker .drift { animation: none; }
  .ticker .lane { overflow-x: auto; }
  .ticker .drift span[aria-hidden="true"] { display: none; }
  .ticker-stop { display: none; }
  .hero-copy .live i { animation: none; }
  .pc, .pc-label, .pc-key, .copy-a, .copy-b { animation: none !important; }
  /* The stage arrives already apart, so the scroll line and the toggle have
     nothing left to do. */
  .stage-foot .hint, .stage-foot label { display: none; }
  .stage { height: auto; } .stage-pin { position: static; height: auto; }
  .pc { transform: translate(var(--tx, 0), var(--ty, 0)) rotate(var(--rot, 0deg)) scale(var(--sc, 1)); }
  .pc-shift { transform: none; }
  .pc-label, .pc-key, .copy-b { opacity: 1; } .pc.glass, .copy-a { opacity: 0; }
  .shots img, .angles img { transition: none; }
  /* The stage arrives apart, so the JS toggle has nothing left to do either. */
  .stage-foot .blow-btn { display: none; }
}

/* legal pages */
.legal-page { padding-bottom: 112px; }
.legal-page .lede { max-width: 58ch; }
.legal-date { display: block; margin-top: 26px; font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.legal-jump { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 9px 26px; padding-bottom: 15px; border-bottom: 2px solid var(--ink); font-family: var(--f-mono); font-size: 11.5px; }
.legal-jump a { display: inline-flex; align-items: center; min-height: 24px; color: var(--muted); }
.legal-jump a:hover { color: var(--violet); }
.legal-body { margin-top: 42px; max-width: 64ch; }
.legal-body section { scroll-margin-top: 22px; }
.legal-body section + section { margin-top: 40px; }
.legal-body h2 { margin-bottom: 4px; }
.legal-body p { margin-top: 15px; font-size: 16.5px; line-height: 1.6; }
.legal-body li { position: relative; margin-top: 13px; padding-left: 22px; font-size: 16.5px; line-height: 1.6; }
.legal-body li::before { content: ""; position: absolute; left: 0; top: .72em; width: 9px; height: 1px; background: var(--violet); }
.legal-body li b { color: var(--ink); font-weight: 500; }
.legal-body .note { padding: 17px 20px; background: var(--canvas); font-size: 15.5px; }
.legal-fine { margin-top: 46px; padding-top: 16px; border-top: 1px solid var(--hair); font-family: var(--f-mono); font-size: 11.5px; color: var(--muted); }
.legal-fine a { border-bottom: 1px solid var(--hair); }

/* consent bar. The page makes room for it so the bar never sits over the
   link or button that has focus. */
body:has([data-consent]:not([hidden])) { padding-bottom: 108px; }
html:has([data-consent]:not([hidden])) { scroll-padding-bottom: 116px; }
.consent { position: fixed; inset: auto 0 0 0; z-index: 40; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 26px; padding: 14px var(--gutter); background: var(--bone); border-top: 1px solid var(--hair-md); }
.consent-copy { max-width: 66ch; font-size: 14px; line-height: 1.45; color: var(--text); }
.consent-lbl { font-family: var(--f-mono); font-size: 10px; letter-spacing: .12em; color: var(--muted); }
.consent-more { border-bottom: 1px solid var(--hair); color: var(--ink); }
.consent-more:hover { color: var(--violet); border-bottom-color: var(--violet); }
.consent-acts { display: flex; align-items: center; gap: 10px; }
.consent-yes, .consent-no { height: 36px; padding: 0 18px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.consent-yes { color: var(--bone); background: var(--violet); border: 1px solid var(--violet); }
.consent-yes:hover { background: #5A2F98; border-color: #5A2F98; }
.consent-no { color: var(--ink); background: transparent; border: 1px solid var(--hair-md); }
.consent-no:hover { border-color: var(--ink); }
.consent-yes:focus-visible, .consent-no:focus-visible, .consent-more:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
@media (max-width: 620px) {
  .consent { gap: 12px; }
  .consent-acts { width: 100%; }
  .consent-yes, .consent-no { flex: 1; }
  /* The bar stacks here, so it needs more room kept under the page. */
  body:has([data-consent]:not([hidden])) { padding-bottom: 172px; }
  html:has([data-consent]:not([hidden])) { scroll-padding-bottom: 180px; }
}

/* fixers: legal */
.summary .sum-tax { margin-top: 10px; font-size: 13px; line-height: 1.5; color: var(--text-soft); }
.legal-switch { margin-top: 16px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.legal-switch button { height: 36px; padding: 0 18px; font-family: var(--f-mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink); background: transparent; border: 1px solid var(--hair-md); cursor: pointer; }
.legal-switch button:hover { border-color: var(--ink); }
.legal-switch button[aria-pressed="true"] { color: var(--bone); background: var(--violet); border-color: var(--violet); }
.legal-switch button:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
.legal-switch .hint { font-size: 13.5px; line-height: 1.5; color: var(--text-soft); }

/* fixers: content correctness */
/* A listing with no photos yet says so in the shot box, instead of borrowing
   another item's picture. */
.shots .cap:empty { display: none; }
.shots .empty { position: absolute; inset: 0; display: grid; place-content: center; padding: 0 28px; text-align: center; font-family: var(--f-mono); font-size: 12px; line-height: 1.7; color: var(--text-soft); }
/* The condition note as prose, beside the price on a part page. */
.notes-body p { margin-top: 12px; max-width: 68ch; font-size: 14.5px; line-height: 1.55; color: var(--text); }
.notes-body p:first-child { margin-top: 0; }
/* Under the six steps on /about, and in place of the terms panel once an item is gone. */
.step-out-note { margin-top: 12px; font-size: 13.5px; line-height: 1.5; color: var(--on-dark-soft); }
.sold-line { margin-top: 20px; font-size: 14.5px; line-height: 1.5; color: var(--text-soft); }
.sold-line a { border-bottom: 1px solid var(--hair-md); color: var(--ink); }
.sold-line a:hover { color: var(--violet); border-bottom-color: var(--violet); }

/* fixers: app correctness and security */
/* What a form says when a post comes back to it with an error code. */
.form-error { margin-bottom: 14px; padding: 10px 13px; border-left: 3px solid var(--violet); background: var(--canvas); font-size: 14.5px; line-height: 1.45; color: var(--ink); }
.form-error.on-dark { background: rgba(157, 107, 232, .14); border-left-color: var(--violet-lt); color: var(--bone); }
.error-acts { display: flex; flex-wrap: wrap; gap: 12px; }

/* ==========================================================================
   fixers: accessibility beyond axe
   ========================================================================== */

/* The exploded drawing is decorative and out of the tab order, so the key
   under it carries the links. The key fades in with the explosion, which
   would leave a focused link invisible, so focus brings the key back. */
.pc-key a { color: inherit; }
.pc-key:has(a:focus-visible) { animation: none; opacity: 1; }

/* The stage toggle. Same box as the checkbox label it stands in for; it says
   one thing at a time and carries the pressed state. */
.stage-foot .blow-btn { display: inline-flex; align-items: center; height: 34px; padding: 0 14px; border: 1px solid var(--hair-md); background: transparent; font-family: var(--f-mono); font-size: 11px; color: var(--ink); cursor: pointer; }
.stage-foot [hidden] { display: none; }

/* The consent bar is laid out with display:flex, which beats the browser's
   own rule for [hidden], so the bar showed up again on every page after it
   had been answered. Hidden means hidden. */
.consent[hidden] { display: none; }

/* What a page says when scripting is off. */
.no-js { margin-top: 18px; padding: 13px 15px; background: var(--canvas); font-size: 14.5px; line-height: 1.55; color: var(--text); }
.no-js a { color: var(--violet); border-bottom: 1px solid rgba(106,58,178,.4); }

/* Windows high contrast and the like: the hollow PC in the lockup is a text
   stroke over transparent letters, and forced colours drop the stroke, so the
   letters would go missing. Fill them instead. */
@media (forced-colors: active) {
  .lockup .pc, .lockup.on-dark .pc { color: CanvasText; -webkit-text-stroke: 0; }
  .site-header, .site-footer, .notice, .consent { border-color: CanvasText; }
}

/* Asked for more contrast, push each soft grey towards its own ground:
   --muted sits on paper so it darkens, --muted-dk sits on ink and plum so it
   lifts, and the hairlines stop being hints. */
@media (prefers-contrast: more) {
  :root {
    --muted: #453E4C;
    --muted-dk: #C6BFCE;
    --text-soft: #322C38;
    --on-dark-soft: #DCD6E2;
    --on-dark-link: #EDE8F2;
    --hair: rgba(27,18,32,.42);
    --hair-lt: rgba(27,18,32,.38);
    --hair-md: rgba(27,18,32,.55);
    --hair-dk: rgba(242,239,234,.5);
  }
}

/* On paper: black on white, nothing pinned, no navigation, and every link on
   the two legal pages says where it goes. */
@media print {
  *, *::before, *::after { background: transparent !important; color: #000 !important; box-shadow: none !important; }
  :root { --hair: #666; --hair-lt: #666; --hair-md: #444; --hair-dk: #666; }
  html, body { background: #fff !important; }
  body { padding-bottom: 0; }
  .skip, .hnav, .hactions, .hsheet, .notice, .site-footer nav, .consent, .legal-jump { display: none; }
  .stage { height: auto; }
  .stage-pin { position: static; height: auto; overflow: visible; }
  .facts { position: static; }
  .legal-body a[href^="/"]::after { content: " (sullypc.com" attr(href) ")"; font-family: var(--f-mono); font-size: .82em; }
  .legal-body a[href^="http"]::after { content: " (" attr(href) ")"; font-family: var(--f-mono); font-size: .82em; }
}
/* fixers: head, seo, structured data, performance */
/* Every photo that gained a WebP sibling now sits inside <picture>. The
   wrapper must not become a box of its own, or the layout rules above would
   land on it instead of on the <img> they were written for. */
picture { display: contents; }

/* fixers: legal round 3 */
/* The warranty disclaimer, the build warranty and the liability cap have to
   be seen before they can be relied on, so each one sits in a bordered box
   with an uppercase mono lead line instead of running on in body text. */
.legal-box { margin-top: 20px; padding: 18px 20px 20px; background: var(--canvas); border: 2px solid var(--ink); }
.legal-body .legal-box p { margin-top: 13px; font-size: 16.5px; }
.legal-body .legal-box p:first-child { margin-top: 0; }
.legal-body .legal-box .legal-box-lead { font-family: var(--f-mono); font-size: 17px; line-height: 1.45;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink); }

/* The line above each submit button that ties the send to the terms. It sits
   on paper on the tray and on ink in the brief band, so it has both. */
.assent { margin-top: 14px; font-size: 15px; line-height: 1.5; color: var(--text); }
.assent a { color: var(--violet); border-bottom: 1px solid rgba(106,58,178,.4); }
.assent.on-dark { color: var(--on-dark-soft); }
.assent.on-dark a { color: var(--on-dark-link); border-bottom-color: var(--hair-dk); }

/* fixers: round 4 */
/* The budget slider was 16px of target on a phone. The track and the thumb
   are the browser's own and are untouched; the box around them is 24px so a
   thumb is not the smallest thing on the form to hit. */
input[type=range] { height: 24px; }

/* The build terms split into subsections under the one warranty heading, so
   /terms needs a third heading level: smaller than the h2s that open a
   section, and set apart enough that "paying for a build" does not read as
   another paragraph of the warranty above it. */
.legal-sub { margin-top: 34px; scroll-margin-top: 22px; font-family: var(--f-head); font-size: 17.5px;
  font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; color: var(--ink); }
.legal-body .legal-sub + p { margin-top: 6px; }

/* Bench USB: the line under a test log naming what ran it. Quieter and smaller
   than the paragraph below it, and mono like everything the bench writes. */
.log-panel .log-tools { margin-top: 12px; font-size: 11.5px; letter-spacing: .02em; color: var(--on-dark-soft); }

/* ==========================================================================
   design round
   ========================================================================== */

/* What the three equal cards under a listing turned into: one line of text,
   the way you would say it out loud. */
.also-line { margin-top: 34px; padding-top: 16px; border-top: 1px solid var(--hair);
  font-size: 15px; line-height: 1.8; color: var(--text-soft); }
.also-line a { color: var(--ink); border-bottom: 1px solid var(--hair-md); }
.also-line a:hover { color: var(--violet); border-bottom-color: var(--violet); }
/* The cards used to carry the bottom of this page; the grid does now. */
.part-grid { margin-bottom: 86px; }
/* The buy column's table took on the four lines from the panel above it, and
   a wrapped key beside a wrapped value reads as two columns of soup. */
.buy .kv .k { white-space: nowrap; }

/* The four small pages each end on something now instead of on 60vh of
   empty paper: the ticket on the two sent pages, a receipt line after a
   payment, three bench rows on a 404. */
.sent-ticket { margin-top: 32px; max-width: 470px; }
.sent-ticket .body p { margin-top: 16px; }
.plain .sent-ticket + .btn { margin-top: 34px; }
.plain .receipt-line { max-width: none; font-family: var(--f-mono); font-size: 14px; line-height: 1.7; }
.plain .receipt-line b { color: var(--ink); font-weight: 500; }
.plain .bench-lead { margin-top: 46px; padding-bottom: 12px; border-bottom: 2px solid var(--ink);
  font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); }
.plain .rows .row { text-decoration: none; }
.plain .rows .row:hover .row-name { color: var(--violet); }

/* The bench row leads with the listing's own photo. A listing without one
   gets no picture and no grey box standing in for it, so the label sits
   where the picture would have started. */
.row-id .row-shot { display: block; width: 100%; max-width: 100%; aspect-ratio: 3 / 2;
  object-fit: cover; margin-bottom: 9px; background: var(--canvas); }
.row .row-id .cat { display: block; padding-top: 0; }
.row .chip { margin-top: 3px; }
.row .right { padding-top: 2px; }
/* The build page delivers what the strip promises: the whole parts list
   under a count, the description as what the machine was for, and the line
   about where the burn-in numbers went. */
.buy .what-for, .buy .parts-lead { display: block; margin-top: 26px; }
.buy .what-for + .story { margin-top: 8px; }
.buy .parts-lead + .kv { margin-top: 10px; }
.buy .handover { margin-top: 18px; font-size: 14px; line-height: 1.5; color: var(--text-soft); }
.wcard .more { display: inline-block; margin-top: 12px; font-family: var(--f-mono); font-size: 11.5px;
  letter-spacing: .04em; color: var(--violet); }
.wcard .more:hover { border-bottom: 1px solid var(--violet); }

/* The condition note moved out of the third tab and up beside the price,
   which is where a used-item buyer looks for it. */
.buy .condition-note { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--hair); }
.buy .condition-note p { max-width: none; font-size: 15px; }

@media (max-width: 980px) {
  .hero-grid, .two, .band .two, .intro, .part-grid, .builds-top, .brief-grid, .about-top, .steps-grid, .who-grid, .tray-grid { grid-template-columns: minmax(0, 1fr); }
  .hero-fig img { height: 320px; }
  .three { grid-template-columns: minmax(0, 1fr); }
  .detail { grid-template-columns: minmax(0, 1fr); }
  .row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 10px; }
  .row .row-id, .row .row-main { grid-column: 1 / -1; padding-top: 0; }
  .row .chip { grid-column: 1; } .row .right { grid-column: 2; }
  .shots, .angles { height: 320px; }
  /* Stacked, the title, the price and the button belong above the photo and
     the log rather than under a screen and a half of them. */
  .part-grid > .buy { order: -1; }
  /* The tray stacks here too, so its lines do: a title long enough to wrap
     was leaving the price floating in the middle of the row. */
  .tray-line { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
  .tray-line .cat { grid-column: 1 / -1; }
  .wcard { width: min(360px, 80vw); }
  .facts { position: static; }
  /* The row stacks here, and a full-width photo would turn nine listings
     into nine screens. */
  .row-id .row-shot { width: 136px; margin-bottom: 11px; }
}
