/* ══ THE MERGE ════════════════════════════════════════════════════════════════
   B's objects and overlays, C's editorial structure, A's photo styling — one
   skin. Chris, 2026-08-29: "a mix of B and C... I like a lot of the stylings
   of A... more of what we saw on the first page of the EPK."
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── shared furniture ── */
.topbar{gap:20px}
.topbar .brand{display:flex;align-items:center;gap:9px;color:var(--bone);text-decoration:none}
.topbar .nv{display:flex;gap:18px;margin-left:auto;margin-right:16px}
.topbar .nv a{color:var(--gray);text-decoration:none;font-size:10.5px;letter-spacing:.16em}
.topbar .nv a.on,.topbar .nv a:hover{color:var(--acid)}
@media(max-width:820px){.topbar .nv{display:none}}
a{color:inherit}
.sub{font-size:15px;color:#D6D4CE;line-height:1.6;margin-top:12px;max-width:44ch}
.lead{font-size:15.5px;line-height:1.72;color:#D2D0CA;max-width:66ch}
p{font-size:14px;line-height:1.7;color:#C5C3BD;max-width:66ch;margin-top:12px}
h2{font-size:clamp(28px,4vw,44px)}
h3,h4,h5{font-family:'Anton',sans-serif;font-weight:400;text-transform:uppercase;letter-spacing:.01em}
.mk{display:inline-block;transform:rotate(-1.8deg);margin-top:10px;font-size:18px;opacity:.94}
.pg{font-family:'Space Mono',monospace;font-size:9.5px;letter-spacing:.2em;color:var(--gray)}
.dek{font-family:'Permanent Marker',cursive;font-size:16px;color:var(--acid);transform:rotate(-1.2deg);display:inline-block}
.fine{font-size:12px;color:var(--gray);margin-top:14px}
.cta{margin-top:20px}
.rw{display:flex;justify-content:space-between;gap:18px;border-top:1px solid var(--line);padding:9px 0;font-size:13px;color:#D2D0CA}
.rw span:first-child{font-family:'Space Mono',monospace;font-size:9.5px;letter-spacing:.16em;color:var(--gray);text-transform:uppercase;flex:none;padding-top:2px}
.rw span:last-child{text-align:right;overflow-wrap:anywhere}
.strip{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:var(--line)}
.strip div{height:190px;background-size:cover;filter:contrast(1.07)}
.strip.big div{height:300px}
@media(max-width:760px){.strip{grid-template-columns:1fr 1fr}.strip div,.strip.big div{height:150px}}
.sect{padding:38px 40px;position:relative;overflow:hidden}
.sect>*:not(.ghost):not(.num){position:relative;z-index:1}
.sect .ghost{right:-70px;bottom:-90px;width:420px}
.back{padding:34px 40px 42px;position:relative;overflow:hidden;border-top:1px solid var(--line)}
.back>*:not(.ghost):not(.num){position:relative;z-index:1}
.back .ghost{right:-80px;bottom:-110px;width:440px}
.back.big{text-align:center;padding:52px 40px}
.back.big h3{font-size:clamp(24px,3.4vw,38px)}
.back.chris{display:grid;grid-template-columns:300px 1fr;gap:32px;align-items:center}
.back .cph{min-height:340px;background-size:cover;filter:contrast(1.07)}
.foot{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:var(--line);border-top:1px solid var(--line)}
.foot .fcol{background:var(--panel);padding:22px 24px 26px}
.foot p{font-size:12.5px;color:#B4B2AC;margin-top:8px;line-height:1.65}
.foot a{color:var(--acid);text-decoration:none}
@media(max-width:760px){.foot{grid-template-columns:1fr}
  .sect{padding:28px 20px}.back{padding:26px 20px 34px}
  .back.chris{grid-template-columns:1fr;gap:0}.back .cph{min-height:260px}}

/* ── the artist page top: one composited hero, everything actionable beside it ──
   hero.py already put the wordmark behind the head in pixels, so the page just shows
   the file. Chris asked for the player and the links "near the very, very top", so
   nothing sits above the fold but the picture, play, and where to follow. */
.atop{display:grid;grid-template-columns:minmax(300px,46%) 1fr;gap:0;background:var(--line)}
.hshot{display:block;width:100%;height:100%;object-fit:cover;background:#111}
.aside{background:var(--panel);padding:38px 38px 40px;display:flex;flex-direction:column;justify-content:center}
/* line-height 1, and the misprint plates OFF artist headlines.
   MEASURED on the live site: 38px type on 32.68px of leading collided by 25.4px.
   Chris: "it has his name said there twice, which should not be that overlapping
   rule." The em needs naming separately because `.mis em` in _stank.css carries
   its OWN pair of plates.
   ⚠️ THIS LIVES IN previews/skin.css BECAUSE THAT IS THE SOURCE. It was fixed in
   site/skin.css on 2026-09-02 and publish_site.py copied previews over the top of
   it, silently putting the bug back. Same shape as the stale homepage: previews/
   is the source, site/ is output. Never edit site/*.css directly. */
.aside h1{font-family:'Anton',sans-serif;font-size:clamp(38px,4.6vw,64px);line-height:1;
  text-transform:uppercase;margin:10px 0 6px}
.aside h1.mis,.aside h1.mis em{text-shadow:none}
.aside h1 em{font-style:normal;color:var(--acid);display:block}
.aside .soc{margin-top:16px}
.aside .cta{align-self:flex-start}

/* the player — a real clip, not a decorative waveform */
/* ── the clip player (previews/player.js) ────────────────────────────────────
   Chris: "a normal-ass music player... not so basic." The native controls are a
   different design system wearing our colours badly — grey pill, blue focus ring,
   a different shape on every browser. So the <audio> stays as the engine and is
   hidden, and the transport is ours: round play button in the ARTIST'S colour, a
   real waveform that also scrubs, one mono time readout. */
.play{margin-top:22px;border-top:2px solid var(--acid);
  border-bottom:1px solid var(--line);padding:14px 0 16px}
.pmeta{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:12px}
.pmeta b{font-family:'Anton',sans-serif;font-size:19px;font-weight:400;text-transform:uppercase}
.pmeta span{font-family:'Space Mono',monospace;font-size:9.5px;letter-spacing:.14em;color:var(--gray)}
.play audio{display:none}
.prow{display:flex;align-items:center;gap:14px}
.pbtn{flex:none;width:52px;height:52px;border-radius:50%;border:0;cursor:pointer;
  background:var(--acid);display:grid;place-items:center;padding:0;
  transition:transform .12s ease}
.pbtn:hover{transform:scale(1.06)}
.pbtn:active{transform:scale(.96)}
.pbtn:focus-visible{outline:2px solid var(--bone);outline-offset:3px}
.pbtn .picon{width:24px;height:24px;fill:#0C0C0C;margin-left:2px}
.play.on .pbtn .picon{margin-left:0}
.pwave{flex:1 1 auto;min-width:0;height:46px;cursor:pointer;position:relative}
.pwave canvas{display:block;width:100%;height:100%}
.pwave:focus-visible{outline:2px solid var(--acid);outline-offset:3px}
.ptime{flex:none;font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.1em;
  color:var(--gray);min-width:34px;text-align:right}
@media(max-width:420px){.pbtn{width:46px;height:46px}.pwave{height:40px}}

.asect{padding:34px 40px 30px}
.asect.spec{border-top:1px solid var(--line)}
.asect .rw{max-width:640px}
.quiet{color:var(--gray);font-size:13px}
.creds{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:2px;
  background:var(--line);border-top:1px solid var(--line)}
.creds>div{background:var(--panel);padding:20px 20px 24px}
.creds h5{font-size:14px;color:var(--acid);margin-bottom:8px}
.creds ul{list-style:none}
.creds li{font-size:13px;color:#C5C3BD;padding:5px 0;border-top:1px solid var(--line)}
/* ⚠️ THE DIRECT-SUPPORT ROW, AND IT SITS AT THE TOP OF THE SUPPORT COLUMN — not on the
   venues board, where it briefly and wrongly lived. Chris, 2026-08-31, relaying
   Beastifull: "At the very top where it says support... her name... and then maybe a
   hyphen and direct support." So: the artist's name at full weight, the billing after it
   in the accent, and a rule under the group to close it off from the shared bills below.
   Every other name in the column is a shared bill; this one is a slot she opened. */
.creds li.bill{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;
  font-size:14px;color:var(--paper);padding:7px 0}
.creds li.bill b{font-weight:700}
.creds li.bill i{font-family:'Space Mono',monospace;font-style:normal;font-size:9.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--acid)}
.creds li.bill+li{border-top:1px solid var(--acid)}
@media(max-width:860px){
  .atop{grid-template-columns:1fr}
  .aside{padding:26px 20px 30px}
  .asect{padding:26px 20px 24px}}

/* ── the record object (home) ── */
.desk{padding:44px 40px 34px;display:grid;grid-template-columns:minmax(300px,480px) 1fr;
  gap:46px;align-items:center;position:relative;
  background:radial-gradient(120% 100% at 24% 10%,#16160F 0,var(--ink) 62%)}
.obj{position:relative;z-index:1;aspect-ratio:1/1;width:100%;container-type:inline-size}
.list{position:relative;z-index:2}
.sleeve{position:absolute;inset:0;z-index:3;overflow:hidden;background:#111;
  box-shadow:0 26px 60px rgba(0,0,0,.72),inset 0 0 0 1px rgba(245,243,238,.09)}
.sleeve .art{position:absolute;inset:0;background-size:cover;filter:contrast(1.12) saturate(1.02)}
.sleeve .dot{position:absolute;inset:0;background:url(tex-sunroof-grit.png) 50% 34%/cover;mix-blend-mode:screen;opacity:.15}
.sleeve .wm{position:absolute;left:0;right:0;top:5%;z-index:2;text-align:center;font-family:'Anton',sans-serif;
  font-size:19cqw;line-height:.85;letter-spacing:.02em;text-transform:uppercase;padding:0 4%}
.obj.wm-ink .sleeve .wm{color:var(--ink);text-shadow:0 1px 0 rgba(255,255,255,.3)}
.obj.wm-bone .sleeve .wm{color:var(--bone);text-shadow:0 3px 18px rgba(0,0,0,.75)}
/* the head over the title — the EPK move at sleeve scale */
.sleeve .scut{position:absolute;inset:0;z-index:3;width:100%;height:100%;object-fit:cover;
  object-position:50% 34%;
  -webkit-mask-image:linear-gradient(180deg,#000 0,#000 58%,transparent 74%);
  mask-image:linear-gradient(180deg,#000 0,#000 58%,transparent 74%)}
.sleeve .fade{position:absolute;inset:0;z-index:4;background:linear-gradient(0deg,rgba(12,12,12,.94) 4%,rgba(12,12,12,0) 46%)}
.sleeve .cat{position:absolute;z-index:5;left:18px;bottom:16px;font-family:'Space Mono',monospace;
  font-size:10px;letter-spacing:.2em;color:#CFCDC7}
.sleeve .cat b{display:block;color:var(--acid);font-weight:400;margin-top:4px}
.sleeve::after{content:"";position:absolute;inset:0;z-index:6;pointer-events:none;
  box-shadow:inset 0 0 44px rgba(0,0,0,.55),inset 0 0 0 1px rgba(0,0,0,.5)}
/* The record is a PHOTOGRAPH of the real thing now (Chris sent it 2026-08-30), not
   three stacked gradients. memory/craft.md: real materials and wear are what stop a
   page reading as machine-made, and a pressed record with actual groove highlights
   is the single most on-brand object we own. The label is baked into the photo, so
   the WHOLE disc turns — which is what a record does. */
.disc{position:absolute;top:9%;left:30%;width:80%;aspect-ratio:1/1;border-radius:50%;z-index:1;
  filter:drop-shadow(0 20px 46px rgba(0,0,0,.75))}
.disc img{display:block;width:100%;height:auto}
/* ⚠️ pspin was deleted in round 5 with the pull-down vinyl, but two rules still
   called it — the sleeve label and the arcade's record wall. Both have been frozen
   since. A missing @keyframes fails silently; nothing in CSS tells you. */
@keyframes pspin{from{transform:rotate(0)}to{transform:rotate(360deg)}}
.disc.spin img{animation:pspin 9s linear infinite}
@media(prefers-reduced-motion:reduce){.disc.spin img{animation:none}}
/* CALMER LIST — Chris: "all these extra fonts... can feel excessive." One face for
   the headline, one quiet sub, no sticker + scrawl pileup on the open. */
.list h1{font-family:'Anton',sans-serif;font-size:clamp(38px,5.2vw,66px);line-height:.87;text-transform:uppercase;margin-top:10px}
.list h1 em{font-style:normal;color:var(--acid);display:block}
.side{font-family:'Space Mono',monospace;font-size:10px;letter-spacing:.26em;color:var(--acid);
  border-bottom:2px solid var(--acid);padding-bottom:6px;margin:24px 0 0}
.trk{display:flex;align-items:center;gap:14px;border-bottom:1px solid var(--line);padding:11px 0;
  text-decoration:none;color:inherit}
a.trk:hover{background:rgba(155,232,0,.05)}
.trk .no{font-family:'Space Mono',monospace;font-size:10px;color:var(--gray);width:24px;flex:none}
.trk .th{width:56px;height:56px;flex:none;background-size:cover;filter:contrast(1.1) grayscale(.15)}
.trk .nm{flex:1}
.trk .nm b{display:block;font-family:'Anton',sans-serif;font-size:19px;text-transform:uppercase;font-weight:400;line-height:1.1}
.trk .nm span{font-size:11.5px;color:var(--gray)}
.trk .dur{font-family:'Anton',sans-serif;font-size:18px;color:var(--acid)}
.proof{display:flex;border-top:2px solid var(--acid);border-bottom:1px solid var(--line);background:var(--panel)}
.proof div{flex:1;padding:15px 18px;border-right:1px solid var(--line)}
.proof div:last-child{border-right:none}
.proof b{display:block;font-family:'Anton',sans-serif;font-size:clamp(24px,3.6vw,36px);line-height:1;color:var(--acid)}
.proof span{font-family:'Space Mono',monospace;font-size:9px;letter-spacing:.14em;color:var(--gray);text-transform:uppercase}

/* ── liner / quote ── */
.liner{display:grid;grid-template-columns:1.25fr .75fr;background:var(--line);border-top:1px solid var(--line)}
.liner>div{background:var(--panel);padding:34px 36px 32px;position:relative;overflow:hidden}
.liner>div>*:not(.ghost){position:relative;z-index:1}
.liner .ghost{left:-90px;bottom:-120px;width:460px}
.liner .q .tex{position:absolute;inset:0;z-index:0;background:url(tex-wire-dots.png) center/cover;opacity:.11;mix-blend-mode:screen}
.liner .q .qt{font-family:'Permanent Marker',cursive;font-size:23px;line-height:1.34;color:var(--bone);margin-top:10px}
.liner .q .by{font-family:'Space Mono',monospace;font-size:9.5px;letter-spacing:.16em;color:var(--gray);margin-top:16px}

/* ── features (home) ── */
.feat{display:grid;grid-template-columns:360px 1fr;background:var(--line);border-top:1px solid var(--line)}
.feat.flip{grid-template-columns:1fr 360px}
.feat .ph{min-height:380px;background-size:cover;filter:contrast(1.08);display:block}
.feat .cp{background:var(--panel);padding:30px 34px}
.feat h3{font-size:clamp(34px,4.6vw,52px);line-height:.92;margin:6px 0 5px}

/* ── text boxes: long copy always sits on solid black (round 5) ── */
.tbox{background:var(--ink);border:1px solid var(--line);padding:22px 24px 24px;max-width:640px}
.tbox .qt{font-size:22px;line-height:1.34;color:var(--bone);margin-top:8px}
.tbox .by{font-family:'Space Mono',monospace;font-size:9.5px;letter-spacing:.16em;color:var(--gray);margin-top:14px}
.tbox .go{display:inline-block;margin-top:14px;font-family:'Space Mono',monospace;font-size:10px;
  letter-spacing:.16em;color:var(--acid);text-transform:uppercase}

/* ── the founder block: his face, his words, first person ── */
.tbox.founder{display:grid;grid-template-columns:190px 1fr;gap:22px;align-items:center;max-width:900px}
.fphoto{width:190px;height:230px;background-size:cover;filter:contrast(1.06)}
.tbox.founder h2{font-size:clamp(24px,3.2vw,34px);margin-bottom:8px}
.tbox.founder .cta{margin-top:16px}
@media(max-width:700px){.tbox.founder{grid-template-columns:1fr}
  .fphoto{width:100%;height:220px}}

/* headline on one line — his call */
.list h1.oneline{white-space:nowrap;font-size:clamp(30px,7.4vw,62px)}
@media(max-width:420px){.list h1.oneline{font-size:8.2vw}}

/* ── the liner: crowd video as the BACK layer, boxes on top ── */
.liner2{position:relative;overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.liner2 video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.28;filter:saturate(1.1)}
.l2sc{position:absolute;inset:0;background:linear-gradient(90deg,rgba(12,12,12,.75) 0,rgba(12,12,12,.35) 100%)}
.l2in{position:relative;z-index:2;display:grid;grid-template-columns:1.2fr .8fr;gap:22px;
  padding:44px 40px;align-items:start}
@media(max-width:820px){.l2in{grid-template-columns:1fr;padding:28px 20px}}

/* ── index features: soft photo back, box front ── */
.feat2{position:relative;display:block;min-height:600px;overflow:hidden;
  border-top:1px solid var(--line);text-decoration:none;color:inherit}
/* ⚠️ THE "VINYL MARKS OVER THE PHOTOS" WERE THIS LINE. The tile photo sat at 38%
   opacity, so the body's groove texture showed straight THROUGH it — it was never an
   overlay on top, it was the page showing through a see-through photo. Full strength
   is the fix, and it is also what he asked for on its own terms. */
.feat2 .f2bg{position:absolute;inset:0;background-size:cover;
  /* --ty / --ty-m are COMPUTED per photo per breakpoint by tile_pos() in
     build_site.py: the right value depends on the TILE's aspect, and the tile is
     2.4:1 on a desktop and 0.85:1 on a phone. The old constant 18% was correct on
     a phone and cut a subject's head off at the eyebrows on a desktop. 18% is only a
     fallback for when the subject cannot be measured. */
  background-position:center var(--ty,18%);
  background-color:var(--ink)}
/* ⚠️ NO SCRIM. Chris, 2026-08-30: "the photos and the vinyl marks need to be changed
   and just have no overlay over it, just the button on top of the photo." The
   gradient wash and the groove texture are both gone — the photograph runs at full
   strength and the ONLY thing over it is the box. That box has to carry its own
   contrast now, because there is no wash helping it: solid ink, not a tint. */
.feat2.flip{justify-content:flex-end}
/* ⚠️ A SLIM BAR, NOT A PLATE. The logo box was two-thirds the height of the tile and
   said the artist's name twice — once as a mark, once on the button. Chris: "make
   that thinner or at least delete it... make it a slim button near the bottom of the
   photo" and let the arrow "go all across". So the photograph is the tile and the
   only thing on it is one bar the full width of the frame. */
.feat2 .f2bar{position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;justify-content:space-between;align-items:center;gap:14px;
  background:#0C0C0C;padding:13px 20px}
.feat2 .f2nm{font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.16em;
  text-transform:uppercase}
/* The mark is stylised — her drips, his gothic — so the NAME has to be spelled out
   somewhere legible. Chris: "the full name ... should be spelt out so that they can
   press on the button." It goes ON the button rather than as a second headline under
   the logo, which just said the same word twice in two typefaces. */
.feat2 .f2go{font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--bone)}
.feat2:hover .f2go{color:var(--acid)}
.feat2 .dek{display:block;margin-bottom:2px}
.feat2:hover .go{color:var(--bone)}
@media(max-width:760px){.feat2,.feat2.flip{min-height:520px}
  .feat2 .f2bg{background-position:center var(--ty-m,18%)}}

/* ══ ⚠️ THE TILE STOPS BEING FULL-BLEED ON A WIDE SCREEN — 2026-08-31 ══════════════
   Chris, with a photo of his ultrawide monitor: "It needs to be taller on the website.
   It looks fine on the mobile site... it just has their head sticking out, which looks
   very poor. Please fix that... Make it the full-body thing."

   THE GEOMETRY IS THE WHOLE ANSWER, and it is why "just make it taller" cannot work.
   A full-bleed tile is as wide as the window. On his monitor that is ~1900px, and the
   artist frames are 4:5 portraits — so showing one whole, edge to edge, would need a
   tile 2,375px TALL. `cover` does the only other thing available and crops a horizontal
   band out of the middle, which is the head he is looking at. Raising min-height from
   600 to 900 would still be a band; it would just be a taller band.

   So above 900px the photograph stops being the background and becomes a PANEL at its
   own 4:5, with the artist's own dim theme filling the rest of the row. Nothing is
   letterboxed and there are no grey bars — the ground is a deliberate colour, which is
   the thing Chris rejected before ("it has the gray area that should not be there").
   Below 900px nothing changes except more height: a phone is already portrait, the
   full-bleed crop works there, and he said so himself.

   ⚠️ THE TWO BREAKPOINTS ARE DIFFERENT SHAPES ON PURPOSE, which he authorised: "It
   could be one length on the website and one other length on the mobile." Recorded in
   THIS-WEEK.md as a standing note so nobody later "fixes" the inconsistency.
   tools/ci/check_desktop.py fails the build if a tile ever squashes below 4:5 again. */
@media(min-width:901px){
  /* ⚠️ THE COLUMN IS SIZED, NOT THE PHOTO. First attempt gave .f2bg an aspect-ratio and
     let the grid size the column — and a grid row stretches its items, so the stretch won
     and the panel came out 910x760 (1.2:1) on an ultrawide. Still landscape, still a
     crop, just a nicer-looking one. Measured, which is the only reason it was caught.
     The column now has a real width and the photo's height follows from its own 4:5, so
     the frame is portrait at every width by construction rather than by hope. */
  .feat2{display:grid;grid-template-columns:clamp(320px,40vw,660px) minmax(0,1fr);
    min-height:0;align-items:start;background:var(--ink)}
  .feat2 .f2bg{position:relative;inset:auto;aspect-ratio:4/5;
    width:100%;height:auto;background-position:center top;background-size:cover}
  .feat2 .f2side{align-self:stretch}
  /* the ground beside the photo — the artist's own colour, not a grey bar */
  /* ⚠️ CENTRED, NOT BOTTOM-ALIGNED. Bottom-aligning the name left the top two thirds of
     a 1,180px-wide panel completely empty on an ultrawide, which reads as a page that
     failed to load rather than as space. The block is centred and the name scales with
     the viewport so it has presence at 1900px instead of sitting at its 86px cap. */
  .feat2 .f2side{position:relative;display:flex;flex-direction:column;
    justify-content:center;padding:44px 48px;min-width:0;
    background:linear-gradient(180deg,var(--ink) 0%,var(--f2c,#141414) 260%)}
  .feat2 .f2big{font-family:Anton,sans-serif;font-size:clamp(44px,6.4vw,124px);
    line-height:.94;letter-spacing:-.01em;text-transform:uppercase;
    color:var(--f2a,var(--bone));margin:0 0 10px;text-wrap:balance}
  .feat2 .f2sub{font-family:'Space Mono',monospace;font-size:11.5px;letter-spacing:.16em;
    text-transform:uppercase;color:var(--smoke);margin:0 0 26px}
  .feat2 .f2bar{position:relative;left:auto;right:auto;bottom:auto;background:none;
    padding:0;border-top:1px solid var(--line);padding-top:16px}
  .feat2 .f2nm{display:none}
  /* ⚠️ FLIPPING THE ORDER MUST FLIP THE COLUMNS TOO. Reordering alone dropped the photo
     into the 1fr column and it ballooned to 1340x1675 on an ultrawide — right aspect,
     absurd size. The measurement caught it; the render looked plausible. */
  .feat2.flip{grid-template-columns:minmax(0,1fr) clamp(320px,40vw,660px)}
  .feat2.flip .f2bg{order:2}
  .feat2.flip .f2side{order:1}
}
@media(max-width:900px){.feat2 .f2side{display:none}}
/* the tile carries two bars — one inside the side panel for desktop, one over the photo
   for the phone — and exactly one is ever shown */
@media(min-width:901px){.feat2>.f2bar{display:none}}

/* ── roster cover + spreads ── */
.mag{position:relative;overflow:hidden;background:var(--ink)}
.mag>img{display:block;width:100%;filter:contrast(1.08) saturate(1.05)}
.mag .vig{position:absolute;inset:0;background:linear-gradient(180deg,rgba(245,243,238,.34) 0,rgba(245,243,238,0) 21%,rgba(12,12,12,0) 62%,rgba(12,12,12,.4) 100%)}
.head{position:absolute;top:1vw;left:0;right:0;z-index:4;padding:0 2.2vw;text-align:center}
.head .wm{display:block;font-family:'Anton',sans-serif;font-size:14vw;line-height:.78;letter-spacing:-.014em;
  text-transform:uppercase;color:var(--ink);text-shadow:0 .3vw 2.4vw rgba(255,255,255,.5)}
.head .rule{display:flex;align-items:center;gap:12px;margin:.7vw .6vw 0;color:var(--ink)}
.head .rule i{flex:1;height:2px;background:var(--ink);opacity:.75}
.head .rule span{font-family:'Space Mono',monospace;font-size:clamp(7px,.85vw,11px);letter-spacing:.3em;white-space:nowrap;text-shadow:0 1px 6px rgba(255,255,255,.75)}
.lines{position:relative;display:flex;align-items:flex-end;justify-content:space-between;gap:34px;
  padding:22px 30px 24px;background:var(--ink);border-bottom:1px solid var(--line)}
.lines .big{max-width:52%}
.lines .big h1{font-family:'Anton',sans-serif;font-size:clamp(30px,5vw,64px);line-height:.86;text-transform:uppercase}
.lines .big h1 em{font-style:normal;color:var(--acid);display:block}
.lines ul{list-style:none;text-align:right;max-width:40%}
.lines li{font-size:13.5px;color:#E4E2DC;padding:7px 0;border-bottom:1px solid rgba(245,243,238,.2)}
.lines li:last-child{border-bottom:none}
.lines li b{display:block;font-family:'Space Mono',monospace;font-size:9px;letter-spacing:.17em;color:var(--acid);font-weight:400;margin-bottom:2px}
.spd{display:grid;grid-template-columns:40% 1fr;background:var(--line);gap:2px;border-top:1px solid var(--line)}
.spd.flip{grid-template-columns:1fr 40%}
.spd.flip .spd-ph{order:2}
.spd-ph{min-height:760px;background-size:cover;filter:contrast(1.07);display:block}
.spd-cp{background:var(--panel);padding:32px 34px 36px}
.spd-cp h2{margin:6px 0 4px}
.spd-cp .strip{margin-top:18px}
.spd-cp .strip div{height:120px}

/* socials — icon + handle, plain black rows, hairline separation (round 4) */
.soc{margin-top:18px;border-top:1px solid var(--line)}
.soc a{display:flex;align-items:center;gap:12px;background:var(--ink);padding:13px 4px;
  text-decoration:none;border-bottom:1px solid var(--line);color:#E4E2DC;font-size:14px}
.soc a:hover span{color:var(--acid)}
.soc svg{width:19px;height:19px;color:var(--acid);flex:none}
.soc span{overflow-wrap:anywhere}

/* ── artist feature page ── */
.feature{display:grid;grid-template-columns:1fr 340px;background:var(--line);gap:2px;border-top:1px solid var(--line)}
.fmain,.fside{background:var(--panel);padding:34px 36px 36px}
.drop::first-letter{font-family:'Anton',sans-serif;font-size:74px;line-height:.78;float:left;padding:6px 12px 0 0;color:var(--acid)}
.pull-q{font-family:'Permanent Marker',cursive;font-size:24px;line-height:1.3;color:var(--bone);
  border-top:2px solid var(--acid);border-bottom:2px solid var(--acid);padding:14px 0;margin:20px 0}
.rws{margin-top:14px}
.fside h4{font-size:17px;color:var(--acid);margin-bottom:10px}
.fside a{color:var(--acid);text-decoration:none}
.lists{margin-top:20px}
.lists>div{margin-bottom:16px}
.lists h5{font-size:13px;color:var(--acid);margin-bottom:4px}
.lists ul{list-style:none}
.lists li{font-size:12.5px;color:#C5C3BD;padding:4px 0;border-top:1px solid var(--line)}

/* ── the backdrop board: dates over a dimmed photo (the pattern Chris kept) ── */
.bboard{position:relative;overflow:hidden;border-top:1px solid var(--line)}
.bph{position:absolute;inset:0;background-size:cover;filter:contrast(1.05) saturate(.9)}
.bsc{position:absolute;inset:0;background:linear-gradient(90deg,rgba(12,12,12,.94) 0,rgba(12,12,12,.82) 46%,rgba(12,12,12,.45) 100%)}
.bin{position:relative;z-index:2;padding:40px;max-width:640px}
.brow{display:flex;justify-content:space-between;gap:20px;border-bottom:1px solid rgba(245,243,238,.16);padding:13px 0}
.brow span:first-child{font-family:'Anton',sans-serif;font-size:19px;text-transform:uppercase;line-height:1.15}
.brow span:last-child{font-family:'Space Mono',monospace;font-size:10.5px;letter-spacing:.1em;color:var(--acid);flex:none;padding-top:5px}
/* a release row that has a real URL behind it — same row, now obviously pressable */
a.brow{text-decoration:none;color:inherit;transition:color .15s}
a.brow:hover span:first-child,a.brow:focus-visible span:first-child{color:var(--acid)}
a.brow:focus-visible{outline:2px solid var(--acid);outline-offset:3px}

/* the scrolling video band on the homepage */
.vband{position:relative;overflow:hidden;min-height:380px;display:flex;align-items:center;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.vband video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:contrast(1.06) saturate(1.12)}
.vbsc{position:absolute;inset:0;background:linear-gradient(90deg,rgba(12,12,12,.88) 0,rgba(12,12,12,.45) 55%,rgba(12,12,12,.2) 100%)}
.vbtx{position:relative;z-index:2;padding:44px 40px;max-width:560px}
.vbtx h2{font-size:clamp(30px,4.4vw,52px)}
@media(max-width:760px){.vband{min-height:300px}.vbtx{padding:30px 20px}}

/* ── booking ── */
.vhero{position:relative;overflow:hidden;min-height:480px;display:flex;align-items:flex-end}
.vhero video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:contrast(1.05) saturate(1.1)}
.vsc{position:absolute;inset:0;background:linear-gradient(0deg,var(--ink) 3%,rgba(12,12,12,.3) 40%,rgba(12,12,12,.35) 100%)}
.vtx{position:relative;z-index:3;padding:0 24px 44px 40px;max-width:680px}
.vtx h1{font-family:'Anton',sans-serif;font-size:clamp(44px,6.6vw,88px);line-height:.84;text-transform:uppercase;margin:12px 0 0}
.vtx h1 em{font-style:normal;color:var(--acid);display:block}
.srows{margin-top:20px}
.srow{display:flex;gap:18px;align-items:baseline;border-top:1px solid var(--line);padding:13px 0}
.srow:first-child{border-top:2px solid var(--acid)}
.srow .n{font-family:'Space Mono',monospace;font-size:10px;color:var(--acid);width:30px;flex:none}
.srow .t{flex:1;font-size:13px;color:var(--gray)}
.srow .t b{display:block;font-family:'Anton',sans-serif;font-size:20px;color:var(--bone);text-transform:uppercase;font-weight:400;line-height:1;margin-bottom:5px}
.srow .v{font-family:'Anton',sans-serif;font-size:19px;color:var(--bone)}
/* booking cards: the artist's LOGO behind their head, cut out — never plain text */
.bwall{display:grid;grid-template-columns:1fr 1fr;gap:3px;background:var(--line)}
.bcard{position:relative;overflow:hidden;display:block;background:#111}
.bcard .eph{display:block;width:100%;height:100%;object-fit:cover;filter:contrast(1.04)}
.bcard .bsc2{position:absolute;inset:0;z-index:4;background:linear-gradient(0deg,rgba(12,12,12,.9) 4%,rgba(12,12,12,0) 34%)}
/* ⚠️ A PLATE, NOT BARE TEXT ON A PHOTOGRAPH. Chris's standing rule is "boxes over
   text", and these labels had been relying on a gradient scrim that the rebuilt
   booking page no longer renders — so "hard techno" and the link were sitting
   straight on the picture and vanishing into it. A solid bar is legible over any
   frame; a scrim is legible over the frames you happened to test. */
.bcard .btx{position:absolute;left:0;right:0;bottom:0;z-index:5;display:flex;
  justify-content:space-between;align-items:center;gap:14px;
  background:var(--ink);padding:13px 18px}
.bcard .btx .tag{font-family:'Space Mono',monospace;font-size:10.5px;
  letter-spacing:.14em;text-transform:uppercase}
.bcard .btx .go{color:var(--bone);font-family:'Space Mono',monospace;font-size:10.5px;
  letter-spacing:.12em;text-transform:uppercase}
.bcard:hover .btx .go{color:var(--acid)}
.bcard .tag{font-family:'Permanent Marker',cursive;font-size:18px}
.bcard .go{font-family:'Space Mono',monospace;font-size:10px;letter-spacing:.16em;color:var(--acid)}

/* ── web tab ── */
.whead{padding:52px 40px 44px;position:relative;overflow:hidden}
.whead>*:not(.ghost){position:relative;z-index:1}
.whead .ghost.big{right:-120px;top:-60px;width:560px;opacity:.05}
.whead h1{font-family:'Anton',sans-serif;font-size:clamp(44px,6.6vw,88px);line-height:.84;text-transform:uppercase;margin:12px 0 0}
.whead h1 em{font-style:normal;color:var(--acid);display:block}
.works{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:var(--line);margin-top:18px}
.wk{background:var(--panel);position:relative}
.wk img{display:block;width:100%;filter:contrast(1.05)}
.wk .wtx{padding:14px 16px 16px}
.wk h4{font-size:19px}
.wk span{font-size:12px;color:var(--gray)}
.tiers{display:grid;grid-template-columns:repeat(4,1fr);gap:2px;background:var(--line);margin-top:18px}
.tier{background:var(--panel);padding:20px 18px 24px}
.tier h4{font-size:20px}
.tier b{display:block;font-family:'Anton',sans-serif;font-size:30px;color:var(--acid);margin:6px 0 8px;line-height:1}
.tier p{font-size:12px;color:var(--gray);line-height:1.55;margin:0}

/* the thin web strip on the homepage — round 8, replaces a whole block */
.webstrip{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:20px 40px;background:var(--ink);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);text-decoration:none;color:var(--bone)}
.webstrip span:first-child{font-family:'Anton',sans-serif;font-size:clamp(20px,3vw,30px);
  text-transform:uppercase}
.webstrip .go{font-family:'Space Mono',monospace;font-size:10.5px;letter-spacing:.16em;
  color:var(--acid);white-space:nowrap}
.webstrip:hover span:first-child{color:var(--acid)}
@media(max-width:600px){.webstrip{padding:16px 20px}}

/* ⚠️ THE TILE SCROLLS THE REAL SITE. Chris, 2026-08-30: "whenever I press it, it
   just plays the video. It needs to be a live preview of the site... it would look
   better if it was a slow scroll in the preview box." So the video is gone. Each
   tile holds a TALL capture of the client's actual page (previews/shoot_previews.py)
   in a fixed window, and pressing it holds for a beat and then pans down — his
   words: "wait a couple seconds so you can get a feel for it and then slowly scroll
   down." The window is the frame; the image inside it is what moves.
   The image is inert: you watch the site, you cannot click into it. */
.wk{position:relative;overflow:hidden}
.wk.playable{cursor:pointer}
.wview{position:relative;overflow:hidden;height:230px;background:#0C0C0C}
.wscroll{display:block;width:100%;height:auto;will-change:transform;
  transform:translateY(0);pointer-events:none}
@media(min-width:900px){.wview{height:260px}}
@media(prefers-reduced-motion:reduce){.wscroll{transition:none!important}}
.wplay{position:absolute;top:12px;right:12px;z-index:3;width:30px;height:30px;border-radius:50%;
  display:grid;place-items:center;background:rgba(12,12,12,.72);color:var(--acid);
  font-size:12px;border:1px solid rgba(155,232,0,.5);transition:opacity .2s}
.wk.on .wplay{opacity:0}

/* ── arcade ─────────────────────────────────────────────────────────────────
   Round 9: "needs to look more like an arcade terminal and should not go all the
   way to the edges of the mobile screen in order to allow them to keep scrolling
   off to the side." So the cabinet is inset with real gutters, and the glass is a
   recessed screen with a bezel — everything that happens after a run happens ON
   the glass, not in the page around it. */
.ahead{padding:48px 40px 40px;position:relative;overflow:hidden}
.ahead>*:not(.spinwall){position:relative;z-index:1}
/* Chris, round 5: "I'd like to see more, like stank face logos in the background, like
   the spinning vinyl. That needs to all be there." Three records turning behind the
   masthead at different sizes and speeds — the same object as the pull-down, used as
   wallpaper rather than as a control.
   ⚠️ Round 9 dropped this block while rewriting the cabinets and the markup kept
   emitting .sv, so three unstyled 512px marks stacked down the header. check_clipping
   caught it. Do not delete CSS whose markup still ships. */
.spinwall{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.sv{position:absolute;border-radius:50%;display:grid;place-items:center;opacity:.5;
  background:
    repeating-radial-gradient(circle at 50% 50%,rgba(255,255,255,.05) 0 1px,transparent 1px 3px),
    radial-gradient(circle at 50% 50%,var(--acid) 0 15%,#141414 16% 62%,#0c0c0c 63% 100%);
  box-shadow:inset 0 0 0 1px rgba(245,243,238,.08);animation:pspin linear infinite}
.sv img{width:11%;filter:brightness(0);opacity:.85}
.sv.a{width:300px;height:300px;right:-70px;top:-90px;animation-duration:16s}
.sv.b{width:180px;height:180px;right:190px;bottom:-70px;animation-duration:11s;opacity:.34}
.sv.c{width:120px;height:120px;right:390px;top:16px;animation-duration:7s;opacity:.22}
@media(max-width:900px){.sv.b,.sv.c{display:none}
  .sv.a{width:200px;height:200px;right:-60px;top:-50px;opacity:.32}}
@media(prefers-reduced-motion:reduce){.sv{animation:none}}
.ahead h1{font-family:'Anton',sans-serif;font-size:clamp(46px,7vw,92px);line-height:.84;
  text-transform:uppercase;margin:12px 0 0}
.ahead h1 em{font-style:normal;color:var(--acid);display:block}
.floor{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;padding:16px 40px 40px;
  max-width:1400px;margin:0 auto}
.cab{background:linear-gradient(180deg,#141416 0,#0B0B0D 100%);border:1px solid #2A2A30;
  border-radius:10px;position:relative;overflow:hidden;
  box-shadow:0 18px 40px rgba(0,0,0,.55), inset 0 1px 0 rgba(245,243,238,.06)}
/* the marquee: the lit plate across the top of a real cabinet */
.cab .chead{display:flex;justify-content:space-between;align-items:baseline;
  padding:13px 16px 11px;border-bottom:1px solid #24242B;
  background:linear-gradient(180deg,#1C1C20 0,#101014 100%);
  box-shadow:inset 0 1px 0 rgba(245,243,238,.07)}
.cab h3{font-size:22px;text-shadow:0 0 18px rgba(155,232,0,.28)}
.cab p{font-size:12px;color:var(--gray);padding:0 16px 12px;margin:0;line-height:1.55;min-height:50px}
/* the glass: a recessed screen inside the cabinet */
.cab .glass{position:relative;margin:0 12px 2px;border-radius:6px;overflow:hidden;
  background:#07070A;box-shadow:inset 0 0 0 1px #23232A, inset 0 6px 22px rgba(0,0,0,.9)}
/* scanlines and a corner vignette, painted OVER the canvas and inert to the finger.
   This is the whole difference between "a black box" and "a screen". */
.cab .glass::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3;
  background:
    radial-gradient(120% 100% at 50% 45%,transparent 42%,rgba(0,0,0,.55) 100%),
    repeating-linear-gradient(180deg,rgba(0,0,0,.26) 0 1px,transparent 1px 3px)}
.cab canvas{display:block;width:100%;background:#0A0A08;touch-action:none}
.cab .over{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:10px;padding:18px;
  background:rgba(7,7,10,.86);text-align:center}
.cab .over[hidden]{display:none}
.cab .ovtitle{font-family:'Anton',sans-serif;font-size:30px;text-transform:uppercase;
  color:var(--bone);line-height:1}
.cab .ovline{font-family:'Space Mono',monospace;font-size:10.5px;letter-spacing:.16em;color:#8A8A85}
.cab .signin{width:min(230px,86%);background:#0C0F0C;border:1px solid #24301F;color:var(--acid);
  font:12px 'Space Mono',monospace;letter-spacing:.12em;padding:9px 10px;text-align:center}
.cab .signin[hidden]{display:none}
.cab .signin:focus{outline:none;border-color:var(--acid)}
.cab .ovgo{background:var(--acid);color:var(--ink);border:0;font-family:'Anton',sans-serif;
  font-size:15px;letter-spacing:.06em;text-transform:uppercase;padding:9px 22px;cursor:pointer}
/* the readout strip under the glass */
.cab .cbar{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:11px 16px 14px;margin-top:12px;border-top:1px solid #1E1E24}
.cab .cbar .sc{font-family:'Space Mono',monospace;font-size:12.5px;letter-spacing:.18em;
  color:var(--acid);background:#0C0F0C;border:1px solid #1E241E;padding:5px 10px}
.cab .cbest{font-family:'Space Mono',monospace;font-size:9px;letter-spacing:.14em;color:#6E6E66}

@media(max-width:900px){.floor{grid-template-columns:1fr;padding:10px 22px 34px;gap:20px}
  .whead,.ahead{padding:34px 20px 30px}
  .bwall{grid-template-columns:1fr}.bcard{min-height:440px}
  .works,.tiers{grid-template-columns:1fr 1fr}
  .desk{grid-template-columns:1fr;gap:28px;padding:26px 20px 24px}
  .obj{max-width:400px;margin:0 auto;width:100%}
  .liner,.feat,.feat.flip,.spd,.spd.flip,.feature{grid-template-columns:1fr}
  .spd.flip .spd-ph{order:0}
  .liner>div,.fmain,.fside,.spd-cp{padding:26px 20px}
  .feat .ph{min-height:250px}.spd-ph{min-height:420px}
  .lines{flex-direction:column;align-items:flex-start;padding:18px 20px 12px}
  .lines .big,.lines ul{max-width:100%;width:100%;text-align:left}
  .lines .big h1{font-size:12vw}
  .bin{padding:28px 20px}
  .proof{flex-wrap:wrap}.proof div{flex:1 0 50%;border-bottom:1px solid var(--line)}}
@media(max-width:520px){.works,.tiers{grid-template-columns:1fr}}
/* ── mobile menu (the burger does something now) ── */
.burger{width:auto;background:none;border:0;padding:6px;cursor:pointer;display:none}
.burger i{display:block;width:22px;height:2px;background:var(--bone);
  box-shadow:0 6px 0 var(--bone),0 -6px 0 var(--bone)}
@media(max-width:820px){.burger{display:block}}
.mmenu{position:fixed;inset:0;top:47px;z-index:55;background:rgba(12,12,12,.97)}
.mmenu nav{display:flex;flex-direction:column;padding:26px 24px;gap:4px}
.mmenu a{color:var(--bone);text-decoration:none;font-family:'Anton',sans-serif;
  font-size:30px;text-transform:uppercase;padding:9px 0;border-bottom:1px solid var(--line)}
.mmenu a.on{color:var(--acid)}

/* ── on the books ── */
.books .bhead2{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
.books .count{font-family:'Space Mono',monospace;font-size:10px;letter-spacing:.14em;color:var(--gray)}
.stub{display:flex;align-items:center;gap:18px;border-top:1px solid var(--line);padding:14px 0}
.stub:first-of-type{border-top:2px solid var(--acid)}
.stub .date{flex:none;text-align:center;min-width:52px}
.stub .date .m{font-family:'Space Mono',monospace;font-size:10px;letter-spacing:.18em;
  color:var(--acid);text-transform:uppercase}
.stub .date .d{font-family:'Anton',sans-serif;font-size:30px;line-height:1}
.stub .meta{flex:1}
.stub .meta h3{font-size:20px;line-height:1.1}
.stub .meta p{font-size:12px;color:var(--gray);margin:3px 0 0}
.btn-ghost{background:none;border:1px solid var(--line);color:var(--bone);
  font-family:'Space Mono',monospace;font-size:10px;letter-spacing:.14em;padding:9px 14px;
  cursor:pointer;text-transform:uppercase}
.btn-ghost:hover{border-color:var(--acid);color:var(--acid)}
dialog#showdlg{border:0;padding:0;background:none;max-width:420px;width:92vw}
dialog#showdlg::backdrop{background:rgba(8,8,8,.8)}
.dsheet{background:var(--panel);border:1px solid var(--line);border-top:4px solid var(--acid);
  padding:24px 24px 22px;color:var(--bone)}
.dsheet h3{font-size:26px;margin-bottom:10px}
.dsheet .btn-ghost{margin-top:16px}
.dsheet .cta{display:inline-block;margin:14px 12px 0 0}
/* ⚠️ THE BUG CHRIS SAW. `[hidden]` is a UA rule at specificity (0,1,0); any class
   selector that sets `display` outranks it, so `.dsheet .cta{display:inline-block}`
   kept showing "Get tickets" on every show even though the script had correctly set
   `hidden` on all of them (no show has a ticket URL on file). The button rendered
   with no href, so it was a dead control on a live page. One global guard, because
   this will happen again to the next element someone hides in JS. */
[hidden]{display:none!important}

/* ── the booking form ── */
.bform{max-width:640px;margin-top:16px}
.bform label{display:block;font-family:'Space Mono',monospace;font-size:9.5px;
  letter-spacing:.16em;color:var(--gray);text-transform:uppercase;margin-top:14px}
.bform input,.bform select,.bform textarea{display:block;width:100%;margin-top:6px;
  background:#131311;border:1px solid var(--line);color:var(--bone);
  font:14px 'Space Grotesk',sans-serif;padding:11px 12px}
.bform input:focus,.bform select:focus,.bform textarea:focus{outline:none;border-color:var(--acid)}
.bform .frow{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.bform button{border:0;cursor:pointer;margin-top:18px}
@media(max-width:600px){.bform .frow{grid-template-columns:1fr}}

/* ── THE ORDER FORM: one white SECTION inside a dark page ───────────────────
   ⚠️ Chris, 2026-08-30: "it needs to have a black background. The white just needs to
   be for the booking portion. It needs to be sectioned off like it was in the old zip
   files." He is right and I had it backwards — the first pass flipped the whole
   /booking page to bone, which meant re-theming the nav, the artist cards and the
   footer to survive it, and every one of those was a patch on a mistake. That is what
   made it clunky.

   v1 never did that. `.book{background:var(--bone);color:var(--ink)}` — one section
   inverts, the page around it stays black, and nothing else needs to know. The
   perforated strip is the seam between the two.

   So the inversion is scoped to .book and NOTHING outside it is touched. */
.book{background:var(--bone);color:var(--ink);padding:0 20px 64px;position:relative;
  z-index:1;
  --panel:#FFFFFF;--line:#DEDCD5;--gray:#63635E}
.book h2,.book h3{color:var(--ink)}
/* .mis throws the acid/blood misprint plates behind display type. That is the dark
   site's signature and it reads as mud on bone — v1 set this heading in plain black. */
.book .mis{text-shadow:none}
.book .sub{margin-top:12px;color:#4A4A45;font-size:15px}
/* the tear-off seam, and the catalogue number that makes it an order form */
.book .slip-perf{height:26px;margin:0 -20px 34px;
  background:radial-gradient(circle 5px at 13px 13px,var(--bone) 98%,transparent) 0 0/40px 26px repeat-x,
             var(--ink)}
.book .catno{position:absolute;top:40px;right:20px;color:#8B8B83;
  font-family:'Space Mono',monospace;font-size:10.5px;letter-spacing:.14em}
.book h2.mis{font-size:clamp(34px,8vw,56px);line-height:1}
.book .bform{margin-top:34px;display:grid;grid-template-columns:1fr 1fr;gap:20px}
.book .field{display:flex;flex-direction:column;gap:8px;min-width:0}
.book .field.full{grid-column:1 / -1}
.book .bform label{font-family:'Space Mono',monospace;font-size:11.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink)}
/* heavy fields — they read as things you fill in, which hairlines never do */
.book .bform input,.book .bform select,.book .bform textarea{
  font-family:'Space Grotesk',system-ui,sans-serif;font-size:16px;width:100%;
  padding:14px;border:2px solid var(--ink);background:#fff;color:var(--ink);
  border-radius:0;appearance:none;-webkit-appearance:none}
.book .bform textarea{min-height:130px;resize:vertical}
.book .bform input:focus,.book .bform select:focus,.book .bform textarea:focus{
  outline:2px solid var(--acid);outline-offset:1px}
.book .bform ::placeholder{color:#8B8B83}
/* ink with acid type, full width. An acid sticker on bone is the loudest thing on the
   band and the eye never reaches the fields — v1 got this right. */
.book .bform .send{display:block;width:100%;background:var(--ink);color:var(--acid);
  font-family:'Space Mono',monospace;font-weight:700;font-size:14px;letter-spacing:.1em;
  text-transform:uppercase;padding:18px 28px;border:0;transform:none;box-shadow:none;
  cursor:pointer;text-align:center}
.book .bform .send:hover{background:#000;color:#B4FF1F}
.book .fineprint{margin-top:16px;font-size:14px;color:#6B6B66}
.book .fineprint a{color:var(--ink)}
/* ⚠️ DESKTOP: the order form was 44% of the width with 780px of dead white beside it.
   Chris, 2026-08-31, reviewing on a laptop — it read as unfinished, and it was: this
   block was laid out for a phone and then never given a desktop case, so it just kept
   stacking in the left column at any width.
   Two columns rather than a centred cap, because the space is worth using: the ask sits
   on the left where reading starts, the form sits on the right where the eye lands.
   Rows and columns are placed EXPLICITLY - with auto-placement the sub-heading lands in
   the form's column, which is how this looked broken in the first draft of the fix. */
@media(min-width:900px){
  .book{display:grid;align-items:start;
    /* The left column is narrow ON PURPOSE. A first pass gave it 1fr, which made it
       640px wide holding a heading and two lines — the 780px hole simply moved from
       the right of the form to underneath the heading. It carries three short things,
       so it gets the width of three short things. */
    grid-template-columns:minmax(260px,.62fr) minmax(0,1fr);
    column-gap:clamp(40px,5vw,72px);
    padding-left:clamp(20px,4.5vw,72px);padding-right:clamp(20px,4.5vw,72px)}
  .book .slip-perf{grid-column:1/-1;grid-row:1;margin-left:0;margin-right:0}
  .book h2.mis{grid-column:1;grid-row:2}
  .book .sub{grid-column:1;grid-row:3;max-width:38ch}
  /* .bform carries max-width:640px for the single-column phone layout. In the
     desktop grid the column already bounds it, and leaving the cap on left the
     form 640px wide inside an 830px column with 189px dead beside it — the same
     hole, a third of the size. The column is the constraint here. */
  .book .bform{grid-column:2;grid-row:2/span 3;margin-top:0;align-self:start;
    max-width:none}
  .book .catno{right:clamp(20px,4.5vw,72px)}
}
@media(max-width:640px){.book .bform{grid-template-columns:1fr}
  .book .catno{top:36px;font-size:9.5px}}


/* ══ THE DECK — the homepage is a record now ═══════════════════════════════
   Chris, 2026-09-01, with the July 21 post attached: "update the homepage again to
   just be the spinning wheel like the photo here."

   The composition is his post, read off it directly: record centred and large on ink,
   then the eyebrow, then the wordmark with MGMT. in acid, then one paragraph. Nothing
   else in the frame. The record is the hero and it is also the only interactive thing
   above the fold, which is why it gets the cursor and the hint.

   ⚠️ IT REPLACES THE SLEEVE COMPOSITION, which was built around the group shot on the
   graffiti thrones — a photo with a departed artist in it. One change, two jobs. */
.deck{
  background:var(--ink); text-align:center;
  padding:clamp(34px,7vw,64px) 22px clamp(44px,8vw,78px);
  display:flex; flex-direction:column; align-items:center;
}
.platter{
  width:min(74vw,430px); aspect-ratio:1/1; margin:0 auto clamp(26px,5vw,40px);
  position:relative; cursor:grab; user-select:none; -webkit-user-select:none;
  -webkit-tap-highlight-color:transparent;
  filter:drop-shadow(0 26px 60px rgba(0,0,0,.85));
}
.platter.held{cursor:grabbing}
/* ⚠️ NO `touch-action:none` HERE, and that is deliberate. It is the obvious way to make
   a drag work on a phone and it traps the page: the disc is the biggest thing above the
   fold, so killing scroll over it means a visitor who swipes up to read gets a spinning
   record and a page that will not move. deck.js classifies the first movement instead —
   round the centre is a spin, up the screen is a scroll — and only calls preventDefault
   once it is sure. See the header of deck.js. */
.platter .rec{
  display:block; width:100%; height:auto; border-radius:50%;
  will-change:transform; pointer-events:none;   /* the platter takes the gesture */
}
.dk-eye{
  font-family:'Space Mono',monospace; font-size:11px; letter-spacing:.3em;
  text-transform:uppercase; color:var(--gray); margin:0 0 12px;
}
.dk-mark{
  font-family:'Anton',Impact,sans-serif; font-weight:400; margin:0;
  font-size:clamp(46px,13.5vw,104px); line-height:.86; letter-spacing:.005em;
  text-transform:uppercase; color:var(--bone);
}
.dk-mark em{font-style:normal; color:var(--acid); display:block}
.dk-lede{
  margin:clamp(18px,3vw,26px) auto 0; max-width:34ch;
  font-size:clamp(15.5px,2.1vw,18px); line-height:1.5; color:#C9C7C1;
}
.deck .cta{margin-top:clamp(22px,3.5vw,30px)}
.dk-hint{
  font-family:'Space Mono',monospace; font-size:10px; letter-spacing:.24em;
  text-transform:uppercase; color:#5E5E58; margin:clamp(20px,3vw,28px) 0 0;
}
/* A record nobody can spin should not claim it can be spun. */
@media(prefers-reduced-motion:reduce){
  .platter{cursor:default}
  .dk-hint{display:none}
}
/* ⚠️ THE WHOLE COMPOSITION HAS TO CLEAR THE FOLD ON A LAPTOP. At 1440×900 the phone
   sizing put the record at 430px and the wordmark at 104px, which pushed the paragraph
   and the button off the bottom of the screen — measured, not guessed. A hero whose
   call to action needs a scroll is a hero that is too big. The record still leads; it
   just stops being the only thing you can see. */
@media(min-width:900px){
  .deck{padding:clamp(26px,3.4vw,44px) 22px clamp(34px,4vw,52px)}
  .platter{width:min(30vw,330px); margin-bottom:26px}
  .dk-mark{font-size:clamp(56px,5.6vw,80px)}
  .dk-lede{max-width:46ch; margin-top:18px}
  .deck .cta{margin-top:22px}
  .dk-hint{margin-top:20px}
}
/* A 1280×720 laptop is shorter than it is narrow-limited, so the min-width query above
   does not help it — measured at 72px over. Height is the constraint, so the query is
   on height. Same composition, one size down. */
@media(min-width:900px) and (max-height:800px){
  .deck{padding:22px 22px 30px}
  .platter{width:min(26vw,260px); margin-bottom:20px}
  .dk-mark{font-size:clamp(48px,4.6vw,66px)}
  .dk-lede{margin-top:14px; font-size:16px}
  .deck .cta{margin-top:18px}
  .dk-hint{margin-top:16px}
}
/* The three things, replacing the paragraph. Chris, 2026-09-01: "The quote over there is
   just too long. You could just say something along the lines of: artists management /
   talent development / whatever the fuck. There are three words that we used to use."
   ⚠️ NOT INVENTED. These are the three the v1 site actually printed — "Management,
   bookings, and artist development" — found in archive/site-v1/index.html, so this is a
   restoration rather than new copy. */
.dk-three{
  list-style:none; margin:clamp(18px,3vw,26px) 0 0; padding:0;
  display:flex; flex-direction:column; align-items:center; gap:7px;
}
.dk-three li{
  font-family:'Space Mono',monospace; font-size:clamp(12px,1.6vw,14px);
  letter-spacing:.16em; text-transform:uppercase; color:#C9C7C1; white-space:nowrap;
}
/* ⚠️ STACKED ON A PHONE, ONE ROW ABOVE IT — and the separator only exists in the row.
   The first cut was a single wrapping row with a diamond before every item after the
   first. Three items do not fit on 390px, so it wrapped, and the wrap put a LEADING
   diamond at the start of the second line — a separator with nothing before it. Only
   visible once rendered. Stacking below 560px removes the problem instead of nudging it. */
@media(min-width:560px){
  .dk-three{flex-direction:row; flex-wrap:nowrap; gap:clamp(14px,2.4vw,22px)}
  .dk-three li + li::before{content:"✦"; color:var(--acid);
    margin-right:clamp(14px,2.4vw,22px)}
}

/* ══ THE BLOOD WORLD ═══════════════════════════════════════════════════════
   A deathcore / horrorcore treatment for an artist whose own logo is a blood-drip
   wordmark. It is not a filter over the page. It is one move, done properly: the hero
   photograph ENDS IN A DRIP, as though the picture itself is running, so the page edge
   repeats the logo's own gesture instead of inventing a horror language next to it.

   ⚠️ SCOPED TO [data-world="blood"] AND NOWHERE ELSE. Beastifull is hard techno; her page
   must not inherit a metalcore treatment because it happened to be written into the
   shared stylesheet. One artist, one world.

   ⚠️ NO ARTIST NAMED IN THIS COMMENT. skin.css is SERVED — a comment here is as public as
   the page. The artist this was built for is on hold pending signature, and naming him in
   a stylesheet the whole internet can read would put him on the site by the back door.
   Who it belongs to is in previews/content.py, which is not published. */
.hshot-wrap{position:relative;display:block;line-height:0}
.hshot-wrap .hshot{display:block;width:100%}
[data-world="blood"] .hshot-wrap::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:64px;
  background:var(--ink); pointer-events:none; z-index:2;
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 64' preserveAspectRatio='none'><path d='M0,64 L1200,64 L1200,5 L1160,5 C1160,29.200000000000003 1154.4,49 1144,49 C1133.6,49 1128,29.200000000000003 1128,5 L1109,5 C1109,33.6 1105.85,57 1100,57 C1094.15,57 1091,33.6 1091,5 L1038,5 C1038,29.200000000000003 1034.15,49 1027,49 C1019.85,49 1016,29.200000000000003 1016,5 L997,5 C997,16.0 991.75,25 982,25 C972.25,25 967,16.0 967,5 L929,5 C929,16.0 925.15,25 918,25 C910.85,25 907,16.0 907,5 L841,5 C841,12.700000000000001 835.75,19 826,19 C816.25,19 811,12.700000000000001 811,5 L781,5 C781,23.700000000000003 778.55,39 774,39 C769.45,39 767,23.700000000000003 767,5 L715,5 C715,12.700000000000001 709.4,19 699,19 C688.6,19 683,12.700000000000001 683,5 L641,5 C641,33.6 635.05,57 624,57 C612.95,57 607,33.6 607,5 L580,5 C580,29.200000000000003 577.2,49 572,49 C566.8,49 564,29.200000000000003 564,5 L544,5 C544,29.200000000000003 539.45,49 531,49 C522.55,49 518,29.200000000000003 518,5 L498,5 C498,12.700000000000001 494.5,19 488,19 C481.5,19 478,12.700000000000001 478,5 L437,5 C437,12.700000000000001 432.45,19 424,19 C415.55,19 411,12.700000000000001 411,5 L394,5 C394,29.200000000000003 390.5,49 384,49 C377.5,49 374,29.200000000000003 374,5 L295,5 C295,29.200000000000003 292.55,49 288,49 C283.45,49 281,29.200000000000003 281,5 L235,5 C235,29.200000000000003 232.2,49 227,49 C221.8,49 219,29.200000000000003 219,5 L145,5 C145,12.700000000000001 142.2,19 137,19 C131.8,19 129,12.700000000000001 129,5 L71,5 C71,16.0 66.45,25 58,25 C49.55,25 45,16.0 45,5 L0,5 Z' fill='black'/></svg>") 0 0/100% 100% no-repeat;
  mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 64' preserveAspectRatio='none'><path d='M0,64 L1200,64 L1200,5 L1160,5 C1160,29.200000000000003 1154.4,49 1144,49 C1133.6,49 1128,29.200000000000003 1128,5 L1109,5 C1109,33.6 1105.85,57 1100,57 C1094.15,57 1091,33.6 1091,5 L1038,5 C1038,29.200000000000003 1034.15,49 1027,49 C1019.85,49 1016,29.200000000000003 1016,5 L997,5 C997,16.0 991.75,25 982,25 C972.25,25 967,16.0 967,5 L929,5 C929,16.0 925.15,25 918,25 C910.85,25 907,16.0 907,5 L841,5 C841,12.700000000000001 835.75,19 826,19 C816.25,19 811,12.700000000000001 811,5 L781,5 C781,23.700000000000003 778.55,39 774,39 C769.45,39 767,23.700000000000003 767,5 L715,5 C715,12.700000000000001 709.4,19 699,19 C688.6,19 683,12.700000000000001 683,5 L641,5 C641,33.6 635.05,57 624,57 C612.95,57 607,33.6 607,5 L580,5 C580,29.200000000000003 577.2,49 572,49 C566.8,49 564,29.200000000000003 564,5 L544,5 C544,29.200000000000003 539.45,49 531,49 C522.55,49 518,29.200000000000003 518,5 L498,5 C498,12.700000000000001 494.5,19 488,19 C481.5,19 478,12.700000000000001 478,5 L437,5 C437,12.700000000000001 432.45,19 424,19 C415.55,19 411,12.700000000000001 411,5 L394,5 C394,29.200000000000003 390.5,49 384,49 C377.5,49 374,29.200000000000003 374,5 L295,5 C295,29.200000000000003 292.55,49 288,49 C283.45,49 281,29.200000000000003 281,5 L235,5 C235,29.200000000000003 232.2,49 227,49 C221.8,49 219,29.200000000000003 219,5 L145,5 C145,12.700000000000001 142.2,19 137,19 C131.8,19 129,12.700000000000001 129,5 L71,5 C71,16.0 66.45,25 58,25 C49.55,25 45,16.0 45,5 L0,5 Z' fill='black'/></svg>") 0 0/100% 100% no-repeat;
}
/* A breath of his oxblood at the very bottom of the frame so the drip reads as coming out
   of colour. Kept SHALLOW — the first cut washed the bottom 44% of the photograph red and
   drowned the picture, which is the opposite of what a hero image is for. */
[data-world="blood"] .hshot-wrap::before{
  content:""; position:absolute; inset:auto 0 0 0; height:20%;
  background:linear-gradient(to bottom,transparent,rgba(90,12,8,.42));
  pointer-events:none; z-index:1;
}


/* The drip. An SVG path in a mask so the bottom edge of the photograph is eaten into
   runs of different lengths — irregular on purpose, because an even scallop reads as a
   decorative border and a horror drip has to look like gravity did it. */
/* A wash of his oxblood up from the bottom of the hero, so the drip reads as coming out
   of colour rather than being pasted onto a grey photograph. */
/* The section rules become drips too — same gesture, quieter, so the page holds the world
   below the fold instead of only at the top. */
[data-world="blood"] .kick{border-bottom:2px solid var(--oxblood)}
[data-world="blood"] .rw{border-bottom-color:#2A0F0C}
/* His wordmark, sitting right under the drip so the two read as one gesture — the frame
   bleeds and his name is what it bleeds into. Sized off the page, not the file. */
.amark{display:block;width:min(78%,340px);height:auto;margin:0 0 14px;
  filter:drop-shadow(0 6px 18px rgba(0,0,0,.7))}
@media(min-width:900px){.amark{width:min(52%,300px)}}

/* ══ CLASSIC ADVERTISING — the web-services pricing block ═══════════════════
   Added 2026-09-01 from the style catalogue (library/design/2026-09-01-41-digital-
   art-styles.md). Its entry names this page directly: "one product lit properly on a
   plain seamless ground, a short serif headline with a full stop, total confidence,
   zero decoration. THE TELL: trying to be clever — the style IS the restraint."

   WHY ONLY HERE. Everything else on this site sells a NIGHT, and skewed acid slabs are
   right for that. This block sells a $900-$1,800 build to a venue owner deciding whether
   to wire money to somebody they have not met. Restraint reads as competence to that
   person; hype reads as a risk. It is the ONE light section on a dark site, which is what
   makes it read as deliberate rather than as a different company.

   ⚠️ EVERY COLOUR AND BORDER IS DECLARED, and that is not belt-and-braces. The first
   build of this had the proof line dark-on-dark, "Start a project." pale grey on bone, and
   a stray 1px #242422 border under .proof from the site's own stylesheet stacking into a
   doubled rule. A light panel dropped into a dark site inherits everything it does not
   name. All three passed "the code looks right" and were caught by rendering at 390px and
   reading the computed styles back off every element. */
/* ⚠️ BORDER **AND** BACKGROUND ARE RESET FIRST, then re-declared. Both had to be learned
   twice: the tested preview reset background on .proof, that reset was dropped when this
   CSS was rewritten for shipping, and .proof came straight back as a #0E0E0C dark panel
   sitting on a bone ground. A light section in a dark site inherits everything it does not
   name, and "I already fixed that once" is not a defence when the fix lives in a file that
   got rewritten. */
.cav, .cav *{border:0;background:none}
.cav{background:#EFEDE6;color:#15130F;padding:56px 22px 46px}
.cav, .cav *{color:#15130F}
.cav .kick{font-size:10px;letter-spacing:.22em;color:#6B675C;margin:0 0 18px;display:block}
.cav h2{font-family:Georgia,'Times New Roman',serif;font-weight:400;
  font-size:clamp(30px,8.6vw,46px);line-height:1.04;letter-spacing:-.015em;
  margin:0 0 14px;text-transform:none;text-wrap:balance}
.cav .sub{font-size:14.5px;line-height:1.55;color:#443F36;max-width:34em;margin:0 0 34px}
.cav .cavrule{height:1px;background:#15130F;opacity:.16;margin:0 0 26px}
.cav .row{display:grid;grid-template-columns:1fr auto;gap:6px 18px;
  align-items:baseline;padding:20px 0}
/* ⚠️ BETWEEN rows, not under each. `.row:last-of-type` keys on the ELEMENT type, div —
   and .proof and .close are divs too, so the last div-of-type was never a .row, the last
   row kept its rule, and it stacked against the proof border into a double line. */
.cav .row + .row{border-top:1px solid rgba(21,19,15,.13)}
.cav .nm{font-family:Georgia,'Times New Roman',serif;font-size:20px;margin:0;
  text-transform:none;letter-spacing:0;font-weight:400}
.cav .pr{font-family:Georgia,'Times New Roman',serif;font-size:26px;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.cav .dsc{grid-column:1/-1;font-size:13.4px;line-height:1.62;color:#4A463C;
  max-width:40em;margin:2px 0 0}
.cav .proof{margin:30px 0 0;padding:22px 0 0;border-top:1px solid rgba(21,19,15,.16);
  font-size:13px;line-height:1.6;color:#4A463C}
.cav .proof b{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:#6B675C;font-weight:400;margin:0 0 8px}
.cav .close{margin:34px 0 0;padding-top:24px;border-top:2px solid #15130F;
  display:flex;flex-wrap:wrap;gap:14px 20px;align-items:baseline;
  justify-content:space-between}
.cav .close .say{font-family:Georgia,'Times New Roman',serif;font-size:21px;margin:0}
/* the ONE acid on the block, and it is on the one thing that is an action */
.cav .close a{font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;
  text-decoration:none;border-bottom:2px solid var(--acid);padding-bottom:3px}
.cav .close a:focus-visible{outline:2px solid #15130F;outline-offset:3px}
.cav .who{width:100%;font-family:var(--mono);font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:#6B675C;margin:16px 0 0}

/* ═══════════════════════════════════════════════════════════════════════════════
   2026-09-02 — four things Chris asked for, all of them the same problem:
   flat CSS shapes that read as divs instead of as printed objects.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. THE KIT BAR, beside the headline ──────────────────────────────────────
   "put back that bar that has all the information... right next to his bass DJ tag
   to the right. It needs to be as accessible to grab."  The whole right half of the
   headline row was empty and the links were three scrolls down. */
.headrow{display:grid;grid-template-columns:1fr auto;gap:22px 30px;align-items:end}
.headrow-l{min-width:0}
.kitbar{display:grid;gap:6px;align-content:end;min-width:206px}
.kit{display:flex;align-items:center;gap:11px;text-decoration:none;
  padding:10px 13px;color:var(--bone);
  /* an object, not a row: taped paper on a dark wall, slightly off-square */
  background:rgba(245,243,238,.055);
  border:1px solid rgba(245,243,238,.20);
  box-shadow:inset 0 1px 0 rgba(245,243,238,.10);
  font-family:'Space Mono',monospace;font-size:11.5px;letter-spacing:.13em;
  text-transform:uppercase;transition:background .16s,border-color .16s,transform .16s}
.kit i{font-style:normal;font-size:14px;line-height:1;color:var(--acid);flex:none}
.kit span{flex:1}
.kit b{font-weight:400;opacity:.5}
.kit:hover,.kit:focus-visible{background:var(--acid);border-color:var(--acid);
  color:var(--ink);transform:translateX(-3px);outline:none}
.kit:hover i,.kit:focus-visible i,.kit:hover b,.kit:focus-visible b{color:var(--ink);opacity:1}
@media(max-width:860px){
  .headrow{grid-template-columns:1fr;gap:16px}
  .kitbar{grid-template-columns:1fr 1fr;min-width:0}
}
@media(max-width:400px){.kitbar{grid-template-columns:1fr}}

/* ── 2. SOCIALS ON THE PHOTOGRAPH, transparent ────────────────────────────────
   "move the social links up to where his photo is near the bottom. Icons: no block,
   just kind of see-through buttons, transparent buttons." */
.hshot-wrap{position:relative}
.soc.ghost{position:absolute;left:0;right:0;bottom:0;z-index:3;
  display:flex;gap:9px;flex-wrap:wrap;margin:0;padding:0 18px 18px;
  border-top:0;background:linear-gradient(180deg,transparent,rgba(10,10,10,.55))}
.soc.ghost a{display:inline-flex;align-items:center;gap:9px;padding:9px 14px;
  background:rgba(12,12,12,.30);border:1px solid rgba(245,243,238,.42);
  -webkit-backdrop-filter:blur(7px) saturate(120%);backdrop-filter:blur(7px) saturate(120%);
  color:var(--bone);text-decoration:none;
  font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;transition:background .16s,border-color .16s}
.soc.ghost a svg{width:15px;height:15px;fill:currentColor;flex:none}
.soc.ghost a:hover,.soc.ghost a:focus-visible{background:rgba(12,12,12,.62);
  border-color:var(--acid);color:var(--acid);outline:none}

/* ── 3. THE ROSTER STRIP — a destination, not a hairline ──────────────────────
   "It's a very thin line... it seems like it's too slim and doesn't do anything."
   A 1px rule under a photo is the most default thing a page can do. This is a slab
   with weight, a torn top edge and the artist's own colour behind it. */
/* ⚠️ STAY ABSOLUTE AT THE FOOT OF THE PHOTO. The first version of this block set
   position:relative and overrode `.feat2 .f2bar{position:absolute;bottom:0}` from the
   original rule — which floated the whole slab ABOVE the photograph, so you read the
   artist's name before you saw the artist. Caught by looking at the render. */
.feat2 .f2bar{position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:20px 20px 22px;border-top:0;
  background:linear-gradient(180deg,rgba(12,12,12,.78),var(--ink) 78%)}
.feat2 .f2bar::before{content:"";position:absolute;left:0;right:0;top:-13px;height:14px;
  background:var(--ink);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='14' preserveAspectRatio='none'%3E%3Cpath d='M0 14V6l9 3 7-6 8 5 10-5 7 4 9-5 8 6 10-4 8 5 9-6 7 5 10-4 8 5 9-5 8 6 10-4 7 4 9-6 8 5 10-4 8 5 9-5 7 4 10-5 8 6V14z' fill='%23000'/%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='14' preserveAspectRatio='none'%3E%3Cpath d='M0 14V6l9 3 7-6 8 5 10-5 7 4 9-5 8 6 10-4 8 5 9-6 7 5 10-4 8 5 9-5 8 6 10-4 7 4 9-6 8 5 10-4 8 5 9-5 7 4 10-5 8 6V14z' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask-size:240px 14px;mask-size:240px 14px;mask-repeat:repeat-x}
.feat2 .f2nm{font-family:'Anton',sans-serif;font-size:clamp(26px,7vw,40px);
  letter-spacing:.005em;line-height:.94;text-transform:uppercase}
.feat2 .f2go{display:inline-flex;align-items:center;gap:10px;flex:none;
  font-family:'Space Mono',monospace;font-size:12px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ink);background:var(--acid);
  padding:12px 16px;transform:rotate(-1.1deg);
  box-shadow:0 3px 0 rgba(0,0,0,.55)}
.feat2 .f2go b{font-weight:400;font-size:15px;line-height:1}
.feat2:hover .f2go{color:var(--ink);transform:rotate(-1.1deg) translateY(-2px)}
@media(min-width:901px){.feat2>.f2bar{display:none}}

/* ── 4. THE TICKER IS AN OBJECT NOW ───────────────────────────────────────────
   "The green strip looks a little tacky." It was a pure flat fill of the brightest
   colour in the palette with no material to it — the definition of a plastic div.
   Halftone dots and a toner grain over it, and a torn bottom edge, so it reads as
   something printed and stuck on. The colour did not change. */
.ticker{position:relative;isolation:isolate}
.ticker::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background-image:
    radial-gradient(circle,rgba(12,12,12,.30) .9px,transparent 1.05px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='t'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23t)' opacity='.22'/%3E%3C/svg%3E");
  background-size:4px 4px,120px 120px;mix-blend-mode:multiply;opacity:.55}
.ticker::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:7px;z-index:3;
  background:var(--ink);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='7' preserveAspectRatio='none'%3E%3Cpath d='M0 7V3l6 2 5-3 6 3 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2V7z' fill='%23000'/%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='7' preserveAspectRatio='none'%3E%3Cpath d='M0 7V3l6 2 5-3 6 3 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2 5-2 6 3 5-3 6 2V7z' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask-size:160px 7px;mask-size:160px 7px;mask-repeat:repeat-x}
.ticker span{position:relative;z-index:1}
/* the reversed one is ink-on-dark, so it takes grain but not the multiply screen */
.ticker.rev::before{mix-blend-mode:screen;opacity:.16}

/* ── the artist pages get the same ground the homepage has ────────────────── */
.atop,.asect,.creds,.back{position:relative}
.atop::after,.back::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23g)' opacity='.09'/%3E%3C/svg%3E");
  mix-blend-mode:overlay}
.atop>*,.back>*{position:relative;z-index:1}

/* ═══ 2026-09-02, the overhaul pass ══════════════════════════════════════════ */

/* ── THE ROSTER CALL replaces the two full-bleed artist tiles ───────────────── */
.rostercall{display:block;text-decoration:none;color:var(--bone);position:relative;
  padding:44px 20px 46px;text-align:center;
  border-top:2px solid var(--line);border-bottom:2px solid var(--line);
  background:
    radial-gradient(120% 80% at 50% 0,rgba(155,232,0,.07),transparent 62%),
    var(--ink)}
.rostercall .kick{margin-bottom:10px}
.rc-big{font-family:'Anton',sans-serif;font-size:clamp(40px,11vw,72px);line-height:.9;
  text-transform:uppercase;margin:0}
.rc-big em{font-style:normal;color:var(--acid);display:block}
.rc-names{font-family:'Space Mono',monospace;font-size:12px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--gray);margin:16px 0 22px}
.rc-go{display:inline-flex;align-items:center;gap:10px;
  font-family:'Space Mono',monospace;font-size:12.5px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ink);background:var(--acid);
  padding:14px 20px;transform:rotate(-1.1deg);box-shadow:0 3px 0 rgba(0,0,0,.55)}
.rc-go b{font-weight:400;font-size:15px;line-height:1}
.rostercall:hover .rc-go{transform:rotate(-1.1deg) translateY(-2px)}

/* ── THE HERO RECORD IS SMALLER — "does have the wheel spinning a lot. I don't
      like that. Maybe just put it in a little smaller." ─────────────────────── */
.deck .platter{width:min(52vw,300px)}
.deck .dk-hint{font-size:10.5px;letter-spacing:.20em;opacity:.55}

/* ── THE NAV SEAL: the black ring is the dominant mass, not the white label ───
   Chris: "the icon that's spinning in the top right... the black outside is going
   to be bigger than the small white end piece but that's switched for now."
   He is right — on a real 7" the label is roughly a THIRD of the disc, and this
   was rendering at about two thirds. FIXED IN tools/build_nav.py, not here —
   measured off his own vinyl render as 39%. One authority, not two. */

/* ── MORE MATERIAL ON THE ACID BAND — "the acid band, I think, maybe pops too
      much. It would be better to add more textures to it, kind of fill it out." ── */
.ticker::before{
  background-image:
    radial-gradient(circle,rgba(12,12,12,.42) 1.05px,transparent 1.2px),
    repeating-linear-gradient(90deg,rgba(12,12,12,.16) 0 1px,transparent 1px 5px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='t2'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='4'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23t2)' opacity='.40'/%3E%3C/svg%3E");
  background-size:4px 4px,5px 100%,120px 120px;
  opacity:.78}
/* and a torn TOP edge as well, so the band reads as a strip of paper laid on */
.ticker{margin-top:2px}

/* ═══ /web — THE STUDIO REGISTER ════════════════════════════════════════════════
   Scoped hard to body[data-page="web"]. Nothing here can reach the homepage or an
   artist page, which is the whole reason the data-page hook was added.

   Chris gave this page licence to stray furthest from house style. It spends that
   licence on RESTRAINT rather than on more decoration, because the thing this page
   has to prove is competence, and a page selling web craft is its own sample of
   the work. Loud is free; well-made is not, and only one of them is the pitch. */

/* the whole page is paper now, not just the price list */
body[data-page="web"]{background:#EFEDE6}
body[data-page="web"] .page{background:#EFEDE6}

/* ── THE MISPRINT IS OFF, EVERYWHERE ON THIS PAGE ────────────────────────────
   The red/green offset plates are the single loudest "tacky" signal — at 44px on a
   phone the three plates smear into each other and "We build websites." stops being
   readable at all. They are house language and they stay on the homepage and the
   artist pages, where a smeared poster headline is the point. Here they are noise
   over the argument. */
body[data-page="web"] .mis,
body[data-page="web"] .mis em,
body[data-page="web"] .mis::before,
body[data-page="web"] .mis::after{text-shadow:none;content:none}
body[data-page="web"] .mis::before,
body[data-page="web"] .mis::after{display:none}

/* ── DISPLAY TYPE IS GEORGIA, SET LIKE A DOCUMENT ────────────────────────────
   Anton is a condensed poster face. It is right on a flyer and wrong on a capability
   page, and swapping it is the "full makeover" of the font Chris asked for. Note the
   lowercase: the house sets everything in caps, and simply letting these headlines
   keep their sentence case does more to change the register than the face does. */
body[data-page="web"] h1,
body[data-page="web"] h2,
body[data-page="web"] h3{
  font-family:Georgia,'Times New Roman',serif;
  font-weight:400;text-transform:none;letter-spacing:-.015em;line-height:1.04;
  color:#15130F}
body[data-page="web"] h1{font-size:clamp(42px,9.5vw,86px);margin:6px 0 18px}
body[data-page="web"] h1 em{font-style:italic;display:block;color:#15130F}
body[data-page="web"] h2{font-size:clamp(27px,5.2vw,44px);margin:0 0 14px}

/* body copy stays Space Grotesk — the grotesk against the serif is the pairing, and
   setting the running text in Georgia too would tip the page from studio into essay */
body[data-page="web"] p,
body[data-page="web"] li{color:#3A372F}
body[data-page="web"] .lede{font-size:clamp(17px,2.6vw,20px);line-height:1.5;max-width:34ch}

/* ── THE ACID IS A RULE, NOT A FILL ──────────────────────────────────────────
   One accent, used once per screen, as a line under something. The email link at the
   bottom of this page was already doing exactly this and it is the sharpest detail on
   it, so the rest of the page copies the email link rather than the other way round. */
body[data-page="web"] .kick{
  font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.22em;
  text-transform:uppercase;color:#6F6B60;border-bottom:0;
  display:inline-block;padding-bottom:6px;
  box-shadow:inset 0 -2px 0 0 var(--acid)}
body[data-page="web"] .sect{margin-top:clamp(48px,9vw,90px)}

/* ── THE WORK IS THE ARGUMENT, SO THE SCREENSHOTS GET THE ROOM ───────────────
   Three real live sites is the strongest thing on this page. On paper they read as
   objects laid on a desk rather than as cards in a grid — a hairline, a real shadow,
   no rounded corners, and the caption set as a caption instead of as a card title. */
body[data-page="web"] .port{border:1px solid #D8D4C8;background:#F7F5F0;
  box-shadow:0 18px 34px rgba(21,19,15,.10);margin-bottom:clamp(26px,5vw,40px)}
body[data-page="web"] .port .cap,
body[data-page="web"] .port .body{background:#F7F5F0;padding:16px 18px 18px}
body[data-page="web"] .port h3{font-size:22px;margin:0 0 2px}
body[data-page="web"] .port .role,
body[data-page="web"] .port .sub{font-family:'Space Mono',monospace;font-size:11px;
  letter-spacing:.18em;text-transform:uppercase;color:#6F6B60}

/* the acid ticker belongs to the house, not to this page — a strip of rave tape across
   a capability deck is the exact register clash Chris is pointing at */
body[data-page="web"] .ticker{display:none}

/* the dark footer still closes the page, and the join now reads as intentional */
body[data-page="web"] .foot{border-top:1px solid #15130F}

/* ── /web: the three live sites, laid on the paper ───────────────────────────
   These screenshots are the only real evidence on this page, so they get the room
   and everything around them gets out of the way. The frame is a hairline and a
   shadow — the screenshot is already a dark rectangle, so on paper it reads as an
   object lying on a desk without any help from a card. */
body[data-page="web"] .works{display:block}
body[data-page="web"] .wk{
  background:#F7F5F0;border:1px solid #D8D4C8;box-shadow:0 16px 30px rgba(21,19,15,.11);
  margin:0 0 clamp(24px,5vw,38px)}
body[data-page="web"] .wtx{background:#F7F5F0;padding:15px 17px 17px}
/* the caption is a caption. Anton caps here made every screenshot look like a flyer
   for itself, which is the register the rest of this page just stopped speaking in. */
body[data-page="web"] .wtx h4{
  font-family:Georgia,'Times New Roman',serif;font-weight:400;font-size:21px;
  text-transform:none;letter-spacing:-.01em;color:#15130F;margin:0 0 3px}
body[data-page="web"] .wtx span{
  font-family:'Space Mono',monospace;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:#6F6B60}
/* the play affordance was an acid ring on black; on paper it needs a solid so it does
   not float, and it still has to read as "this one moves" */
body[data-page="web"] .wplay{background:rgba(12,12,12,.62);border-color:var(--acid)}

/* ── the torn black band goes ────────────────────────────────────────────────
   .band is a 38px strip of house texture between the hero and the work. It exists to
   join two dark sections. Both sections are paper now, so it is a black bar across a
   white page with nothing on either side of it to join. */
body[data-page="web"] .band{display:none}

/* the halftone strip above the pricing block was doing the same job and reads as a
   deliberate rule between two paper sections, so it stays — but quieter */
body[data-page="web"] .cav{background:#EFEDE6}

/* ── /web: the last two dark artifacts ───────────────────────────────────────
   Both were house texture doing a job that no longer exists on a paper page.
   .works painted itself #242422 so the cards would sit on a dark gutter; with the
   cards on paper that gutter is a black stripe between them. The torn edge under the
   hero belongs to .whead.tear and tore one dark section away from the next — there is
   only one surface here now, so it tore paper away from paper. */
body[data-page="web"] .works{background:transparent}
body[data-page="web"] .whead.tear::before,
body[data-page="web"] .whead.tear::after{display:none;content:none}

/* ═══ MVCE — THE DRIED RED ══════════════════════════════════════════════════════
   Scoped to body[data-page="mvce"]. Beastifull keeps her bright pillar-box red; this
   is only his page. */

/* ── TYPE ON THE RED GOES BONE ───────────────────────────────────────────────
   The house pairs near-black type on the acid fill, which is right for acid green and
   wrong for a dark red — #0C0C0C on #6E120C is barely legible, and it was already
   marginal on the brighter red. Bone on dried blood is both the readable pair and the
   on-theme one. */
body[data-page="mvce"] .cta,
body[data-page="mvce"] .ticker,
body[data-page="mvce"] .rc-go{color:var(--bone)}
body[data-page="mvce"] .cta{box-shadow:0 3px 0 rgba(0,0,0,.7)}

/* ── THE FLAT FILLS GET GRAIN ────────────────────────────────────────────────
   "Retexturing" is the actual ask, and it is what stops a big red rectangle reading as
   a swatch. Two layers over the fill: a fine noise so the red has tooth, and a slow
   vertical streak so it reads as something that ran and dried rather than something
   that was printed. Both are dark-on-dark, so they cost no contrast. */
body[data-page="mvce"] .cta{position:relative;overflow:hidden}
body[data-page="mvce"] .cta::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:
    repeating-linear-gradient(180deg,rgba(0,0,0,.22) 0 1px,transparent 1px 4px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='b1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23b1)' opacity='.55'/%3E%3C/svg%3E");
  background-size:100% 5px,90px 90px;mix-blend-mode:multiply}

/* the ticker on his page is the same band of tape, but wet rather than printed */
body[data-page="mvce"] .ticker::before{opacity:.55;mix-blend-mode:multiply}
body[data-page="mvce"] .ticker::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.65;
  background:linear-gradient(180deg,rgba(0,0,0,.34),transparent 42%,rgba(0,0,0,.42))}

/* the drop cap is the one place the red is allowed to stay a solid — it is small and it
   is doing the job of a decorated initial — but it gets the same tooth */
body[data-page="mvce"] .rw::first-letter,
body[data-page="mvce"] .drop{text-shadow:0 2px 0 rgba(0,0,0,.45)}

/* ── ITEM 9: THE KIT BAR IS NOT A FORM ───────────────────────────────────────
   Chris: "change the font on that too. Looks tacky." It was Space Mono at 11.5px with
   wide tracking — the house's utility voice, which on a stack of four boxed rows reads
   as a settings screen. Anton is the right face here and it is already loaded: condensed
   caps is the hardcore/metal flyer voice his whole brand is speaking in, so the bar stops
   being chrome and starts being part of the poster. The arrow and the glyph stay mono so
   the row still reads as a control. */
body[data-page="mvce"] .kit span{
  font-family:'Anton',sans-serif;font-size:17px;letter-spacing:.03em;
  text-transform:uppercase;color:var(--bone)}
body[data-page="mvce"] .kit{border-color:rgba(245,243,238,.13)}
body[data-page="mvce"] .kit:hover{border-color:var(--acid);background:rgba(110,18,12,.16)}
body[data-page="mvce"] .kit i{color:var(--acid);opacity:.9}
body[data-page="mvce"] .kit b{font-family:'Space Mono',monospace;color:#8A8A85}

/* ═══ 2026-09-03 — THE PAPERWORK MOVED TO THE BOTTOM ═════════════════════════
   Chris: hero, then the music, then who they are, THEN the documents. The kit bar
   used to sit beside the headline; taking it out is what lifts the player up. */

/* .headrow was a two-column grid built to hold the headline and the kit bar side by
   side. With the bar gone it has ONE child, and `1fr auto` on one child leaves the
   `auto` track empty — harmless, but the gap still reserves space under the headline
   on narrow screens. One column, no gap, nothing to reserve. */
.headrow{grid-template-columns:1fr;gap:0}

/* ⚠️ THE BAR IS WIDE NOW, NOT A NARROW COLUMN. .kitbar carries min-width:206px
   because it used to be the skinny right-hand column of that row. Left alone at the
   bottom of the page it renders as a 206px stub against a full-width section, which
   looks like something failed rather than something moved. */
.kitfoot{padding-top:6px}
.kitfoot .kitbar{min-width:0;gap:8px;max-width:520px}
.kitfoot .kit{padding:14px 15px;font-size:14px}
@media (min-width:760px){
  .kitfoot .kitbar{grid-template-columns:1fr 1fr;max-width:none}
}
