/* ==========================================================================
   CVYSM — site.css
   Announcement bar, navigation, hero, sections, roster, contact, footer, 404.

   Register: CVY family (cvyco.com). Solid black bars pinned top and bottom,
   black serif display type on paper, hairline rules, frosted glass for depth.
   ========================================================================== */

/* ======================= buttons ======================= */
.btn{
  --btn-pad:13px 22px;
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:var(--btn-pad);border-radius:var(--r-xs);border:1px solid transparent;
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  font-weight:500;cursor:pointer;text-align:center;white-space:nowrap;
  transition:transform var(--t) var(--e-out),background var(--t-fast) ease,
             border-color var(--t-fast) ease,color var(--t-fast) ease,box-shadow var(--t) ease;
}
.btn:active{transform:translateY(1px) scale(.99)}
.btn .arw{transition:transform var(--t) var(--e-out)}
.btn:hover .arw{transform:translateX(3px)}

/* solid black — the primary action, as on the reference */
.btn--primary{background:var(--ink);color:var(--on-ink);font-weight:600}
.btn--primary:hover{background:#000;box-shadow:0 12px 26px -14px rgba(10,10,10,.6)}

/* inverted, for use on the black bars */
.btn--onink{
  color:var(--ink);background:var(--on-ink);border-color:var(--on-ink);font-weight:600;
}
.btn--onink:hover{background:#fff;box-shadow:0 12px 26px -14px rgba(255,255,255,.4)}

.btn--outline{color:var(--fg);border-color:var(--hair);background:transparent}
.btn--outline:hover{border-color:var(--ink);background:var(--paper-3)}

.btn--ghost{color:var(--on-ink-mute);border-color:var(--hair-ink);background:transparent}
.btn--ghost:hover{color:var(--on-ink);border-color:var(--on-ink)}

.btn--lg{--btn-pad:17px 32px;font-size:10.5px}

/* ======================= announcement bar =======================
   Thin solid black marquee pinned above the nav — the reference's most
   recognisable move, and the reason the ticker has a job. */
.topbar{
  position:fixed;top:0;left:0;right:0;height:var(--topbar-total);z-index:calc(var(--z-nav) + 1);
  padding-top:var(--safe-t);
  background:var(--ink);color:var(--on-ink);
  display:flex;align-items:center;overflow:hidden;
}
.topbar .ticker-track{display:flex;width:max-content;animation:marquee 46s linear infinite}
.topbar:hover .ticker-track{animation-play-state:paused}
.ticker-group{display:flex;flex:0 0 auto}
.ticker-group > span{
  display:inline-flex;align-items:center;gap:22px;padding-right:22px;
  font-family:var(--display);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-ink);white-space:nowrap;
}
.ticker-group > span::after{content:"";width:3px;height:3px;border-radius:50%;background:var(--on-ink-dim);flex:0 0 auto}
@keyframes marquee{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}

/* ======================= navigation ======================= */
.nav{
  position:fixed;top:var(--topbar-total);left:0;right:0;z-index:var(--z-nav);
  background:var(--ink);color:var(--on-ink);
  border-bottom:1px solid transparent;
  transition:border-color var(--t) ease,box-shadow var(--t) ease;
}
.nav-in{
  max-width:var(--max);margin:0 auto;width:100%;
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:14px var(--gut);height:var(--nav-h);
}
.nav.scrolled{
  border-bottom-color:var(--hair-ink);
  box-shadow:0 12px 30px -26px rgba(0,0,0,.9);
}

.brand{display:flex;align-items:center;gap:11px;color:var(--on-ink);flex:0 0 auto}
.brand .logo--mono{width:26px}
.brand .nm{
  font-family:var(--display);font-weight:500;font-size:17px;
  letter-spacing:.2em;text-indent:.2em;text-transform:uppercase;
}

.nav-links{position:relative;display:flex;align-items:center;gap:4px}
.nav-links a{
  position:relative;z-index:1;
  font-family:var(--display);font-size:14.5px;letter-spacing:.02em;
  color:var(--on-ink-mute);padding:9px 13px;border-radius:var(--r-xs);
  transition:color var(--t-fast) ease;white-space:nowrap;
}
.nav-links a:hover{color:var(--on-ink)}
.nav-links a[aria-current="true"]{color:var(--on-ink)}
/* sliding glass block that settles under the active link */
.nav-pill{
  position:absolute;top:50%;left:0;z-index:0;height:36px;width:60px;
  transform:translate3d(0,-50%,0);border-radius:var(--r-xs);
  background:rgba(255,255,255,.12);
  border:1px solid rgba(255,255,255,.18);
  box-shadow:inset 0 1px 0 0 rgba(255,255,255,.16);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  opacity:0;transition:transform .5s var(--e-spring),width .5s var(--e-spring),opacity var(--t) ease;
}
.nav-pill.on{opacity:1}

.nav-cta{display:flex;align-items:center;gap:10px;flex:0 0 auto}

/* ======================= language toggle =======================
   Sits in the nav beside the CTA, and repeats in the mobile drawer, because on a
   phone the drawer is the only place the nav is reachable and a language switch
   most visitors never find is not a switch. Styled as a small bordered chip so it
   reads as a control rather than as a seventh nav item — the nav already carries
   six and the sliding pill would have to grow to seven. */
.lang{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:38px;height:30px;padding:0 9px;
  border:1px solid var(--hair-ink);border-radius:var(--r-xs);
  font-family:var(--mono);font-size:10.5px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  color:var(--on-ink);white-space:nowrap;
  transition:background var(--t) var(--e-out),border-color var(--t) var(--e-out);
}
.lang:hover,.lang:focus-visible{background:rgba(255,255,255,.10);border-color:var(--on-ink)}
/* the drawer sits on ink too, so the same chip works there — it just takes the
   full width and spells the switch out instead of abbreviating it */
.lang--drawer{
  min-width:0;width:100%;height:auto;padding:14px 16px;justify-content:center;
  font-size:11px;letter-spacing:.14em;text-transform:none;
}

/* hamburger */
.burger{
  display:none;width:44px;height:44px;border-radius:var(--r-xs);
  align-items:center;justify-content:center;
  background:transparent;border:1px solid var(--hair-ink);
  cursor:pointer;color:var(--on-ink);
}
.burger i{position:relative;display:block;width:17px;height:1.5px;background:currentColor;border-radius:2px;
  transition:transform var(--t) var(--e-out),background var(--t-fast)}
.burger i::before,.burger i::after{
  content:"";position:absolute;left:0;width:17px;height:1.5px;background:currentColor;border-radius:2px;
  transition:transform var(--t) var(--e-out),top var(--t) var(--e-out);
}
.burger i::before{top:-5.5px}
.burger i::after{top:5.5px}
.burger[aria-expanded="true"] i{background:transparent}
.burger[aria-expanded="true"] i::before{top:0;transform:rotate(45deg)}
.burger[aria-expanded="true"] i::after{top:0;transform:rotate(-45deg)}

/* scroll progress hairline */
.progress{position:absolute;left:0;right:0;bottom:-1px;height:2px;background:transparent;overflow:hidden}
.progress i{
  display:block;height:100%;width:100%;transform:scaleX(0);transform-origin:0 50%;
  background:var(--on-ink);
}

/* ======================= mobile drawer ======================= */
.drawer{
  position:fixed;inset:0;z-index:var(--z-drawer); /* under the nav, see base.css */
  display:flex;flex-direction:column;
  padding:calc(var(--chrome-h) + 20px) var(--gut) max(var(--gut), var(--safe-b));
  /* on a short phone the drawer's contents exceed the viewport — without this the
     bottom CTAs sit below the fold and cannot be reached at all */
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
  background:rgba(10,10,10,.94);
  -webkit-backdrop-filter:blur(26px) saturate(160%);backdrop-filter:blur(26px) saturate(160%);
  color:var(--on-ink);
  opacity:0;visibility:hidden;transition:opacity var(--t) ease,visibility var(--t) step-end;
}
.drawer.open{opacity:1;visibility:visible;transition:opacity var(--t) ease,visibility 0s}
.drawer-nav{flex:1;display:flex;flex-direction:column;gap:2px;margin-top:8px}
.drawer-nav > a{
  font-family:var(--display);font-size:clamp(24px,6vw,32px);font-weight:500;text-transform:uppercase;
  letter-spacing:.01em;color:var(--on-ink);
  padding:13px 0;border-bottom:1px solid var(--hair-ink);
  display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  opacity:0;transform:translateY(14px);
}
.drawer.open .drawer-nav > a{animation:drawerIn .5s var(--e-out) forwards;animation-delay:calc(var(--i,0) * 55ms + 60ms)}
@keyframes drawerIn{to{opacity:1;transform:none}}
.drawer-nav > a .n{font-family:var(--mono);font-size:10px;letter-spacing:.2em;color:var(--on-ink-dim)}
.drawer-foot{margin-top:auto;padding-top:26px;display:flex;flex-direction:column;gap:14px}
.drawer-foot .btn{font-family:var(--label)} /* not the display face */

/* ======================= hero ======================= */
.hero{
  position:relative;
  min-height:100vh; /* fallback for browsers without svh */
  min-height:100svh;
  display:grid;place-items:center;
  padding:calc(var(--chrome-h) + 30px) var(--gut) clamp(80px,11vh,128px);
  background:var(--paper);
  isolation:isolate;overflow:hidden;
}
/* Oversized so the parallax transform can never expose an edge. The size must be
   given explicitly: a <canvas> with width:auto takes its intrinsic size from its
   own width attribute, and since JS derives that attribute from this element's
   box, an inset-only rule creates a feedback loop that inflates the canvas to the
   browser's 2^25 clamp. max-width:none defeats `img,svg,canvas{max-width:100%}`. */
#lattice{
  position:absolute;
  top:calc(var(--lattice-pad, 48px) * -1);
  left:calc(var(--lattice-pad, 48px) * -1);
  width:calc(100% + var(--lattice-pad, 48px) * 2);
  height:calc(100% + var(--lattice-pad, 48px) * 2);
  max-width:none;z-index:0;opacity:.9;
  transition:opacity .5s ease;will-change:transform;
}
.hero[data-lattice="off"] #lattice{opacity:0}

.lockup{
  position:relative;z-index:2;
  display:flex;flex-direction:column;align-items:center;
  transform-style:preserve-3d;
}
.mark{width:clamp(150px,22vh,290px);color:var(--ink);overflow:visible}
.mark > path{fill:currentColor;opacity:0;transform:translateY(10px) scale(.985);transform-origin:50% 50%}
.ready .mark > path{animation:pop .9s var(--e-out) forwards}
/* the filled mark resolves while the construction drawing is still finishing */
.ready .mark > path:nth-of-type(1){animation-delay:.34s}
.ready .mark > path:nth-of-type(2){animation-delay:.46s}
.ready .mark > path:nth-of-type(3){animation-delay:.56s}
.ready .mark > path:nth-of-type(4){animation-delay:.64s}
@keyframes pop{to{opacity:1;transform:none}}

/* construction drawing: hairline outlines of the mark's own geometry, stroked
   on load. JS measures each path and animates stroke-dashoffset. */
.mark-draw{opacity:.5;pointer-events:none}
.mark-draw path{vector-effect:non-scaling-stroke}

/* raking specular sweep, clipped to the mark */
.sweepbar{opacity:0;transition:opacity .4s ease}
.ready .hero[data-sweep="on"] .sweepbar{opacity:1}
.sweep-g{animation:rake 8.5s cubic-bezier(.5,.02,.42,1) 1.9s infinite}
@keyframes rake{0%,3%{transform:translateX(0)}26%{transform:translateX(1300px)}100%{transform:translateX(1300px)}}
.hero[data-sweep="off"] .sweep-g{animation:none}

.lockup .logo--word{
  width:clamp(150px,21vh,280px);
  margin-top:clamp(22px,3.4vh,46px);
}
.lockup-sub{
  margin-top:clamp(12px,1.8vh,22px);
  font-family:var(--display);font-size:clamp(11px,1.5vh,15px);font-weight:400;
  letter-spacing:.34em;text-indent:.34em;color:var(--fg);
  text-transform:uppercase;text-align:center;
}
.lockup-rule{width:clamp(170px,20vh,270px);height:1px;background:var(--hair);margin-top:clamp(22px,3.2vh,40px)}

/* the display statement — the reference's signature move */
.hero-statement{
  margin-top:clamp(20px,3vh,36px);
  font-family:var(--display);
  font-size:clamp(19px,3.1vw,40px);
  font-weight:500;line-height:1.06;letter-spacing:.005em;
  text-transform:uppercase;color:var(--fg);text-align:center;
  max-width:20ch;text-wrap:balance;
}

.lockup-pb{
  margin-top:clamp(30px,4.4vh,54px);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.3em;text-indent:.3em;
  color:var(--label-c);text-transform:uppercase;
}
.rooted{margin-top:clamp(13px,1.9vh,22px)}
.rooted .logo--rooted{width:clamp(96px,13vh,160px);filter:invert(1)}

.lockup .logo--word,.lockup-sub,.lockup-rule,.lockup-pb,.rooted,.hero-statement{opacity:0}
.ready .lockup .logo--word{animation:rise .8s ease forwards .62s}
.ready .lockup-sub{animation:rise .8s ease forwards .74s}
.ready .lockup-rule{animation:rise .8s ease forwards .84s}
.ready .hero-statement{animation:rise .9s ease forwards .9s}
.ready .lockup-pb{animation:rise .8s ease forwards 1.0s}
.ready .rooted{animation:rise .8s ease forwards 1.08s}
@keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}

/* the wordmark and Rooted artwork is near-white; invert it for the paper ground */
.lockup .logo--word{filter:invert(1)}

.hero[data-lockup="mark"] .logo--word,
.hero[data-lockup="mark"] .lockup-sub,
.hero[data-lockup="mark"] .lockup-rule,
.hero[data-lockup="mark"] .hero-statement,
.hero[data-lockup="mark"] .lockup-pb,
.hero[data-lockup="mark"] .rooted{display:none}
.hero[data-lockup="mark"] .mark{width:clamp(220px,36vh,440px)}

/* hero corner meta */
.corner{
  position:absolute;z-index:2;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--mute);opacity:0;transition:opacity .5s ease .3s;
  display:flex;flex-direction:column;gap:7px;
}
.ready .corner{opacity:1}
.corner.tl{top:calc(var(--chrome-h) + 22px);left:max(var(--gut), var(--safe-l))}
.corner.tr{top:calc(var(--chrome-h) + 22px);right:max(var(--gut), var(--safe-r));text-align:right;align-items:flex-end}
/* --mute, not --dim. These are real 9px words a visitor reads ("Practice",
   "Based"), and --dim is #A3A3A3 — 2.5:1 on the white paper ground, well under
   the 4.5:1 AA floor for body-size text, and a breach of base.css's own note
   that --dim is for "decorative strokes only, never text". axe-core does not
   catch it because the whole .corner block is aria-hidden="true", and axe skips
   hidden nodes: a clean axe pass is not a contrast pass. */
.corner .k{color:var(--mute);font-size:9px}
.corner .v{color:var(--fg)}
@media(max-width:640px){.corner.tr{display:none}}

/* scroll cue */
.cue{
  position:absolute;left:50%;bottom:clamp(28px,4.6vh,50px);transform:translateX(-50%);
  z-index:2;display:flex;flex-direction:column;align-items:center;gap:10px;
  font-family:var(--mono);font-size:9px;letter-spacing:.34em;text-indent:.34em;
  text-transform:uppercase;color:var(--mute);
  opacity:0;transition:opacity .6s ease 1.7s;
}
.ready .cue{opacity:1}
.cue i{display:block;width:1px;height:34px;background:var(--ink);opacity:.45;animation:cuepulse 2.1s ease-in-out infinite}
@keyframes cuepulse{0%,100%{opacity:.12;transform:translateY(0)}50%{opacity:.7;transform:translateY(5px)}}
body.scrolled .cue{opacity:0 !important;transition:none}

/* ======================= short viewports =======================
   The hero stack (mark, wordmark, rule, statement, Rooted) is taller than the
   gap between the pinned bars once the viewport gets short, and the corner meta
   and scroll cue are absolutely positioned — so they collide. Shed the
   decorative chrome and tighten the scale rather than let elements overlap. */
/* on phones the corner meta is wider than the gap beside the lockup, and it
   duplicates information the contact section already carries */
@media (max-width: 700px){
  .corner{display:none}
}
@media (max-height: 780px){
  .corner,.cue{display:none}
  .hero{padding-top:calc(var(--chrome-h) + 18px);padding-bottom:32px}
  .mark{width:clamp(110px,20vh,240px)}
  .lockup .logo--word{width:clamp(110px,19vh,220px);margin-top:18px}
  .lockup-sub{margin-top:10px}
  .lockup-rule{margin-top:16px}
  .hero-statement{margin-top:14px;font-size:clamp(17px,3vw,30px)}
  .lockup-pb{margin-top:24px}
  .rooted{margin-top:10px}
  .rooted .logo--rooted{width:clamp(78px,11vh,130px)}
}
@media (max-height: 620px){
  .mark{width:clamp(88px,16vh,170px)}
  .hero-statement{font-size:clamp(15px,2.4vw,22px)}
  .lockup-pb{margin-top:16px}
  .rooted .logo--rooted{width:clamp(64px,9vh,100px)}
}

/* ======================= services ======================= */
.card{display:flex;flex-direction:column;min-height:100%}
.card .n{
  font-family:var(--mono);font-size:10px;letter-spacing:.22em;color:var(--fg);
  text-transform:uppercase;margin:0 0 18px;
}
.card h3{margin:0 0 10px;font-family:var(--display);font-size:clamp(19px,1.9vw,25px);font-weight:500}
.card p{margin:0;color:var(--mute);font-size:14px;line-height:1.62;max-width:44ch}
.card ul{margin:20px 0 0;padding-top:18px;border-top:1px solid var(--hair-2)}
.card ul li{
  display:flex;gap:10px;align-items:flex-start;
  font-size:13px;color:var(--mute);padding:5px 0;
}
.card ul li::before{
  content:"";flex:0 0 auto;width:5px;height:5px;margin-top:7px;
  background:var(--ink);
}

/* ======================= process timeline ======================= */
.timeline{position:relative;margin-top:clamp(30px,4vw,52px);padding-left:clamp(34px,4vw,52px)}
.timeline::before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:1px;background:var(--hair)}
.timeline .fill{
  position:absolute;left:0;top:6px;width:1px;height:0;background:var(--ink);
}
.step{position:relative;padding:0 0 clamp(28px,3.4vw,46px)}
.step:last-child{padding-bottom:0}
.step::before{
  content:"";position:absolute;left:calc(clamp(34px,4vw,52px) * -1 - 3.5px);top:8px;
  width:8px;height:8px;border-radius:50%;
  background:var(--paper);border:1px solid var(--hair);
  transition:background var(--t) ease,border-color var(--t) ease,box-shadow var(--t) ease;
}
.step.in::before{background:var(--ink);border-color:var(--ink);box-shadow:0 0 0 4px rgba(10,10,10,.08)}
.step .n{font-family:var(--mono);font-size:10px;letter-spacing:.2em;color:var(--label-c);margin:0 0 8px}
.step h3{margin:0 0 8px;font-family:var(--display);font-size:clamp(19px,1.9vw,25px);font-weight:500}
.step p{margin:0;color:var(--mute);font-size:14px;max-width:58ch}
@media(max-width:520px){.timeline{padding-left:26px}.step::before{left:-26px}}

/* ======================= roster ======================= */
.roster{margin-top:clamp(28px,4vw,46px)}
/* The roster is shown in two groups — professional players first, then the
   college and NIL athletes — so the site leads with the pros.
   The second group carries an inset rule above it. That is a grouping device,
   not the doubled-section-rule bug: .sec draws the full-bleed rule at the very
   top of the section and the nearest grid sits a whole row of cards below this
   one, so the two can never be confused the way they were on Services. */
.roster-group{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--label-c);font-weight:500;margin:0 0 20px;
}
.roster-group + .roster{margin-top:0}
/* ======================= roster list =======================
   The roster is a list, not a grid of cards. Each athlete is a full-width row —
   portrait, name, club, tags — stacked under its own group heading, so PROS and
   COLLEGE read as two lists rather than six cards sitting side by side. */
.roster-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}
.roster-list li{border-bottom:1px solid var(--hair)}
.rl-row{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:clamp(14px,2.2vw,30px);
  padding:clamp(12px,1.5vw,18px) 0;
}
.rl-face{
  width:clamp(54px,5.6vw,74px);aspect-ratio:4/5;overflow:hidden;
  border-radius:var(--r-xs);border:1px solid var(--hair);background:var(--plate);
  flex:0 0 auto;
}
.rl-face img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(1) contrast(1.06);
  transition:transform var(--t) var(--e-out);
}
.rl-row:hover .rl-face img{transform:scale(1.04)}
.rl-who{min-width:0}
.rl-name{
  display:block;font-family:var(--display);font-weight:500;
  font-size:clamp(19px,2.1vw,27px);line-height:1.1;color:var(--fg);
}
.rl-club{
  display:block;margin-top:6px;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--label-c);
}
.rl-tags{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end}
@media(max-width:640px){
  .rl-row{grid-template-columns:auto minmax(0,1fr);row-gap:10px}
  .rl-tags{grid-column:2;justify-content:flex-start}
}
.roster-group:not(:first-child){
  margin-top:clamp(40px,5.4vw,72px);
  padding-top:clamp(30px,4vw,48px);
  border-top:1px solid var(--hair);
}
.ath{display:flex;flex-direction:column;align-items:flex-start;min-height:100%}
/* portrait frame. 4:5, matching the processed assets, so every card sits on the
   same ground and the grid reads as one set rather than a collage. */
.ath-photo{
  position:relative;width:100%;aspect-ratio:4/5;border-radius:var(--r-sm);
  border:1px solid var(--hair);background:var(--plate);
  overflow:hidden;margin-bottom:20px;
}
.ath-photo img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .9s var(--e-out);
}
.ath:hover .ath-photo img{transform:scale(1.025)}

/* Fallback: an athlete with no portrait yet. Currently unused, because every
   athlete on the roster has a photograph — but a new signing arrives before their
   shoot does, so this is a live state rather than dead styling. The monogram plate
   sits on the same dark ground as the photographs so the card does not read as
   brighter or broken than the rest of the grid. */
.ath-photo--pending{display:grid;place-items:center}
.ath-photo--pending .logo--mono{
  position:absolute;width:112%;opacity:.10;
  transform:translateY(5%);
  transition:transform var(--t-slow) var(--e-out),opacity var(--t-slow) ease;
}
.ath:hover .ath-photo--pending .logo--mono{transform:translateY(5%) scale(1.04);opacity:.18}
.ath-ini{
  position:relative;font-family:var(--display);font-weight:500;
  font-size:clamp(28px,3.2vw,44px);letter-spacing:.06em;color:var(--on-ink);
}
.ath .nm{
  margin:0 0 7px;font-family:var(--display);font-size:19px;font-weight:500;
  color:var(--fg);letter-spacing:0;
}
.ath .rl{
  margin:0 0 14px;font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--label-c);
}
.ath .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
.ath-note{margin-top:clamp(24px,3vw,34px);padding-top:22px;border-top:1px solid var(--hair)}

/* ======================= the mark / construction plate ======================= */
.plate{
  border-top:1px solid var(--hair);background:var(--paper-2);
  padding:clamp(56px,8vw,116px) 0 clamp(64px,9vw,128px);
}
.plate-in{
  max-width:1120px;margin:0 auto;width:100%;padding-inline:var(--gut);
  display:grid;grid-template-columns:minmax(0,360px) minmax(0,1fr);
  gap:clamp(32px,5vw,76px);align-items:start;
}
@media(max-width:760px){.plate-in{grid-template-columns:1fr}}
.plate h2{font-size:clamp(21px,2.6vw,32px);margin:0 0 18px;text-transform:uppercase;line-height:1.08}
.plate p{margin:0 0 16px;max-width:62ch;font-size:14px;line-height:1.68;color:var(--mute)}
.grid-fig{
  position:relative;border:1px solid var(--hair);background:var(--paper);
  aspect-ratio:1/1;display:grid;place-items:center;padding:14%;overflow:hidden;
  border-radius:var(--r-sm);
}
.grid-fig canvas{position:absolute;inset:0;width:100%;height:100%}
.grid-fig .logo--mono{position:relative;width:100%;filter:invert(1)}

/* dimension annotations — the mark read as a measured technical drawing */
.dim{
  position:absolute;z-index:2;
  display:flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.1em;color:var(--label-c);
  font-variant-numeric:tabular-nums;pointer-events:none;
}
.dim i{position:relative;display:block;background:var(--hair)}
.dim i::before,.dim i::after{content:"";position:absolute;background:var(--hair)}
/* width marker: along the bottom edge, ticks pointing up */
.dim--w{left:14px;right:14px;bottom:11px}
.dim--w i{flex:1;height:1px}
.dim--w i::before,.dim--w i::after{top:-3px;width:1px;height:7px}
.dim--w i::before{left:0}
.dim--w i::after{right:0}
/* height marker: along the right edge, laid out vertically */
.dim--h{top:14px;bottom:14px;right:11px;flex-direction:column}
.dim--h b{writing-mode:vertical-rl}
.dim--h i{flex:1;width:1px}
.dim--h i::before,.dim--h i::after{left:-3px;height:1px;width:7px}
.dim--h i::before{top:0}
.dim--h i::after{bottom:0}
/* registration marks: the corners of a measured drawing */
.reg{position:absolute;width:10px;height:10px;pointer-events:none}
.reg::before,.reg::after{content:"";position:absolute;background:var(--ink);opacity:.28}
.reg::before{width:100%;height:1px}
.reg::after{width:1px;height:100%}
.reg--tl{top:7px;left:7px}
.reg--tr{top:7px;right:7px}
.reg--bl{bottom:7px;left:7px}
.reg--br{bottom:7px;right:7px}
.reg--tl::before,.reg--tr::before{top:0}
.reg--tl::after,.reg--bl::after{left:0}
.reg--tr::after,.reg--br::after{right:0}
.reg--bl::before,.reg--br::before{bottom:0}
@media(max-width:520px){.dim{display:none}}

/* ======================= contact ======================= */
.contact-grid{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(20px,3vw,44px);align-items:start}
@media(max-width:860px){.contact-grid{grid-template-columns:1fr}}
.c-item{display:block;padding:22px 0;border-bottom:1px solid var(--hair)}
.c-item:first-of-type{padding-top:0;border-top:0}
.c-item .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--label-c);margin:0 0 8px}
.c-item .v{font-family:var(--display);font-size:21px;font-weight:500;color:var(--fg);word-break:break-word}
a.c-item:hover .v{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.c-item .sub{color:var(--mute);font-size:13px;margin-top:7px;font-weight:400}

/* form */
.field{position:relative;margin-bottom:16px}
.field label{
  display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--label-c);margin-bottom:9px;
}
.field .req{color:var(--fg)}
.field input,.field textarea,.field select{
  width:100%;padding:14px 16px;border-radius:var(--r-xs);
  background:var(--paper);border:1px solid var(--hair);
  /* >=16px: iOS Safari zooms the viewport on focus for anything smaller */
  color:var(--fg);font-size:16px;font-family:var(--label);
  transition:border-color var(--t-fast) ease,background var(--t-fast) ease,box-shadow var(--t) ease;
  -webkit-appearance:none;appearance:none;
}
.field textarea{resize:vertical;min-height:120px;line-height:1.55}
.field input::placeholder,.field textarea::placeholder{color:var(--mute)}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--ink);background:#fff;
  box-shadow:0 0 0 3px rgba(10,10,10,.08);
}
.field select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23555' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;padding-right:42px;
}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:560px){.field-row{grid-template-columns:1fr}}
.form-foot{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;margin-top:22px}
.form-note{font-size:11.5px;color:var(--label-c);max-width:34ch;line-height:1.5}
/* the no-JavaScript note is a real instruction, not a footnote, so it reads at
   body size and takes the full width of the panel */
.form-note--noscript{
  font-size:13.5px;color:var(--body);max-width:52ch;
  margin:0 0 20px;padding:13px 15px;border-left:2px solid var(--ink);
  background:var(--paper-3);
}
.status{
  margin-top:16px;padding:14px 16px;border-radius:var(--r-xs);font-size:13px;
  border:1px solid var(--ink);background:var(--paper-3);color:var(--fg);
}
.status:empty{display:none}
.status.is-err{border-color:#8A1F1F;background:#FBEFEF;color:#7A1B1B}

/* honeypot: visually and accessibly removed, but still a field a bot will fill.
   Without this rule it renders as a real input and a genuine enquiry that
   happened to fill it would be silently discarded. */
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}

/* ======================= footer ======================= */
.foot{
  background:var(--ink);color:var(--on-ink);
  padding:clamp(52px,6.5vw,84px) 0 max(clamp(28px,4vw,40px), var(--safe-b));
}
.foot-top{display:grid;grid-template-columns:minmax(0,1.4fr) repeat(4,minmax(0,1fr));gap:clamp(26px,4vw,52px)}
@media(max-width:820px){.foot-top{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.foot-top{grid-template-columns:1fr}}
.foot .fb{display:flex;align-items:center;gap:11px;color:var(--on-ink);margin-bottom:18px}
.foot .fb .logo--mono{width:24px}
.foot .fb .nm{
  font-family:var(--display);font-weight:500;font-size:16px;
  letter-spacing:.2em;text-indent:.2em;text-transform:uppercase;
}
.foot p{color:var(--on-ink-mute)}
.foot-col h2{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--on-ink-dim);font-weight:500;margin:0 0 16px;
}
.foot-col li{margin-bottom:10px}
.foot-col a{font-size:14px;color:var(--on-ink-mute);transition:color var(--t-fast) ease}
.foot-col a:hover{color:var(--on-ink)}
.foot-mark{margin-top:26px;opacity:.6}
.foot-mark .logo--word{width:148px}
.foot-bot{
  margin-top:clamp(36px,4vw,58px);padding-top:24px;border-top:1px solid var(--hair-ink);
  display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--on-ink-mute);
}
.foot-bot .pb{
  display:inline-flex;align-items:center;gap:10px;margin:0;
  font:inherit;letter-spacing:inherit;color:var(--on-ink-mute);
  text-decoration:none;transition:color var(--t-fast) ease;
}
.foot-bot .pb:hover,.foot-bot .pb:focus-visible{
  color:var(--on-ink);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px;
}
.to-top{display:inline-flex;align-items:center;gap:8px;color:var(--on-ink-mute);transition:color var(--t-fast)}
.to-top:hover{color:var(--on-ink)}

/* ======================= 404 ======================= */
.notfound{min-height:100vh;min-height:100svh;display:grid;place-items:center;text-align:center;padding:var(--gut);background:var(--paper)}
.notfound .logo--mono{width:64px;margin:0 auto 28px;filter:invert(1)}
.notfound .code{font-family:var(--mono);font-size:10px;letter-spacing:.3em;color:var(--label-c);margin-bottom:16px}
.notfound h1{margin-bottom:18px;font-size:clamp(28px,4.4vw,54px);text-transform:uppercase}
.notfound p{color:var(--mute);margin:0 auto 30px;max-width:44ch}

/* ======================= responsive nav ======================= */
@media(max-width:900px){
  .nav-links{display:none}
  .burger{display:inline-flex}
  .nav-cta .btn{display:none}
}
@media(max-width:640px){
  :root{--nav-h:60px;--topbar-h:28px}
  .brand .nm{font-size:14px;letter-spacing:.16em;text-indent:.16em}
  .brand .logo--mono{width:22px}
}

/* ======================= short-viewport drawer =======================
   Six uppercase display links plus two CTAs is a tall stack. Rather than let it
   overflow, scale it to the available height so the CTAs stay on screen. */
@media (max-height:820px){
  .drawer-nav > a{font-size:clamp(21px,5.4vw,26px);padding-block:10px}
  .drawer-foot{padding-top:16px;gap:11px}
  .drawer-foot .btn{min-height:48px}
}
@media (max-height:660px){
  .drawer-nav > a{font-size:clamp(19px,4.9vw,23px);padding-block:8px}
  .drawer-foot{padding-top:12px;gap:9px}
  .drawer-foot .btn{min-height:44px}
}
/* the smallest phones (320x568) still overflowed by 10px */
@media (max-height:600px){
  .drawer-nav > a{padding-block:6px}
  .drawer-foot{padding-top:10px;gap:8px}
}

/* ======================= touch targets =======================
   WCAG 2.5.8 wants at least 24x24, and 44x44 is the comfortable real-world
   figure. Links inside a sentence are exempt (the inline email addresses), but
   standalone nav and footer links are not — they get real padding on touch. */
@media (hover:none) and (pointer:coarse){
  .brand{min-height:44px}
  .foot-col a{display:inline-block;padding-block:13px}
  .foot-col li{margin-bottom:0}
  .to-top{min-height:44px;padding-inline:8px}
  .foot-bot .pb{padding-block:9px}
  .drawer-foot .btn{min-height:52px}
  .nav-links a{padding-block:12px}
}
@media (max-width:720px){
  .foot-col a{display:inline-block;padding-block:12px}
  .foot-col li{margin-bottom:0}
  .to-top{min-height:44px;align-items:center}
}

/* ======================= no-JS fallback =======================
   Every entrance animation on this site is triggered by script, so without
   script the content must simply start in its finished state. Anything that
   is hidden pending a class added by JS has to be forced visible here, or the
   page renders blank. */
html.no-js .rv,
html.no-js .step{opacity:1 !important;transform:none !important;filter:none !important}
html.no-js .mark-draw{display:none}
html.no-js .mark > path,
html.no-js .mark-draw,
html.no-js .lockup .logo--word,
html.no-js .lockup-sub,
html.no-js .lockup-rule,
html.no-js .hero-statement,
html.no-js .lockup-pb,
html.no-js .rooted,
html.no-js .corner,
html.no-js .cue{opacity:1 !important;transform:none !important}

/* the drawer cannot open, so keep the inline links and drop scripted affordances */
html.no-js .nav-links{display:flex !important}
html.no-js .burger{display:none !important}
html.no-js .nav-cta .btn{display:inline-flex}
html.no-js .progress{display:none}
@media(max-width:720px){
  html.no-js .nav-in{flex-wrap:wrap;height:auto;gap:10px;padding-block:12px}
  html.no-js .nav-links{order:3;width:100%;justify-content:space-between;overflow-x:auto}
  html.no-js .nav-links a{padding:8px 6px;font-size:13px}
}

/* nav is tight between the desktop and drawer breakpoints */
@media(min-width:901px) and (max-width:1150px){
  .nav-links a{padding:9px 9px;font-size:13px}
  .nav-cta .btn{--btn-pad:12px 16px;letter-spacing:.14em;font-size:9.5px}
}

/* the hero kicker + trademark artwork are grouped so the phrase is exposed to
   assistive tech as one string rather than two fragments */
/* the attribution links out to project-rooted.com; the text supplies the
   accessible name, so the trademark artwork beside it stays decorative and is
   not announced twice */
.pb-group{display:flex;flex-direction:column;align-items:center;text-decoration:none;color:inherit}
.pb-group:hover .lockup-pb,
.pb-group:focus-visible .lockup-pb{
  color:var(--fg);text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px;
}
