/* GREENE MMA — shared shell.
   Loaded on every public page AFTER the page's inline styles, so rules here
   are site-wide truth. Pages that genuinely differ (index, utah, story,
   privacy, terms) override in a small <style> block placed AFTER this link,
   so their equal-specificity rules win the cascade. */

/* ---------- Design tokens ---------- */
:root{--black:#0C0E0A;--black-2:#13160F;--volt:#C9F73A;--bone:#F2F0E9;--steel:#9AA194;--red:#FF4B3E;--hair:rgba(242,240,233,.14);}

/* ---------- Nav ---------- */
nav{position:sticky;top:0;z-index:50;background:rgba(12,14,10,.94);backdrop-filter:blur(12px);border-bottom:1px solid var(--hair);}
/* Measured: logo 125 + links 579 + league button 162 + gaps = 920px of the
   1060px row, leaving 140px for the fight-week chip. The chip was asking for
   304 because it repeated the bout names, so the row went over and the
   two-word links broke onto a second line — a tall, lopsided bar.
   With the bout names dropped (see below) the whole row measures 1050, so the
   nav stays at the page's own width instead of sprawling wider than the
   content beneath it. A little past 1060 for rendering slack. */
nav .wrap{position:relative;display:flex;align-items:center;justify-content:center;gap:18px;height:58px;max-width:1120px;}
nav .links{display:flex;flex:1;justify-content:center;gap:clamp(14px,2.4vw,34px);font-weight:600;font-size:14px;letter-spacing:.14em;text-transform:uppercase;color:var(--steel);}
/* A link is one word as far as the eye is concerned, whatever its label. */
nav .links a{position:relative;padding:4px 0;white-space:nowrap;}
nav .links a::after{content:'';position:absolute;left:50%;right:50%;bottom:-2px;height:2px;background:var(--volt);transition:left .2s,right .2s;}
nav .links a:hover,nav .links a.on{color:var(--volt);}
nav .links a:hover::after,nav .links a.on::after{left:0;right:0;}
nav .home{display:flex;align-items:center;gap:10px;flex-shrink:0;}
nav .home svg{width:28px;height:28px;flex-shrink:0;transition:transform .2s;}
nav .home:hover svg{transform:rotate(-22.5deg);}
nav .home .wm{font-family:'Anton',sans-serif;font-size:17px;letter-spacing:.02em;text-transform:uppercase;color:var(--bone);white-space:nowrap;}
nav .home .wm b{color:var(--volt);font-weight:400;}
nav .home:hover .wm{color:var(--volt);}
/* Tighten the row before anything has to be dropped, so the bar gets denser
   rather than suddenly losing a piece. Ordered by what can be spared first:
   spacing, then the wordmark, then the fight-week chip. */
@media(max-width:1320px){nav .links{gap:clamp(12px,1.8vw,26px);letter-spacing:.10em;}}
@media(max-width:1140px){nav .home .wm{display:none;}}
/* Below this the six links need every pixel; the chip's information is already
   in the ticker running above the bar. */
@media(max-width:860px){nav .fw-chip{display:none;}}

/* ---- Mobile nav fix: the six links can't fit under ~560px, so on small
   screens the row scrolls sideways with an edge fade (same cue as the
   marquee) instead of clipping or forcing the page to scroll sideways. ---- */
@media(max-width:700px){
  nav .wrap{gap:12px;padding:0 16px;}
  nav .links{
    flex:1 1 auto;min-width:0;justify-content:flex-start;
    overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    gap:24px;font-size:12px;letter-spacing:.08em;padding:6px 0;
    -webkit-mask-image:linear-gradient(90deg,#000 84%,transparent);
    mask-image:linear-gradient(90deg,#000 84%,transparent);
  }
  nav .links::-webkit-scrollbar{display:none;}
  nav .links a{flex-shrink:0;white-space:nowrap;}
}

/* ---------- Footer ---------- */
footer{padding:46px 0 66px;font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--steel);line-height:2.1;}
footer a{color:var(--bone);}
footer a:hover{color:var(--volt);}
/* logo lockup used by the index + utah footers; no-op elsewhere */
footer .top{display:flex;align-items:center;gap:14px;margin-bottom:22px;}
footer .top svg{width:30px;height:30px;}
footer .top .name{font-family:'Anton',sans-serif;font-size:19px;text-transform:uppercase;}
footer .top .name span{color:var(--volt);}
footer .fine{font-family:'JetBrains Mono',monospace;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--steel);line-height:2.1;}
footer .fine a{color:var(--bone);}
footer .fine a:hover{color:var(--volt);}

/* ---------- Generated card art ----------
   Shared by the homepage feed and the archive. Every value has a fallback so
   a card still looks right if the art script never runs; the per-story
   variables come from /assets/cardart.js. Lives in the shared sheet so the
   two feeds cannot drift apart. */
.card .art{
  position:relative;height:96px;margin:-26px -26px 4px;overflow:hidden;
  background:linear-gradient(var(--a-bg-angle,135deg),#161A10 0%,#0D1009 55%,#12160E 100%);
  border-bottom:1px solid var(--hair);
}
.card .art .glow{
  position:absolute;inset:0;
  background:radial-gradient(ellipse var(--a-glow-size,80%) 120% at var(--a-glow-x,10%) var(--a-glow-y,110%),
    rgba(var(--a-tint,201,247,58),.22), transparent 62%);
}
.card .art .stripe{
  position:absolute;top:-40%;left:var(--a-stripe-x,-10%);width:52%;height:190%;
  background:linear-gradient(90deg,transparent,rgba(var(--a-tint,201,247,58),.09),transparent);
  transform:skewX(var(--a-skew,-18deg));transition:transform .5s ease;
}
.card .art .dots{
  position:absolute;inset:0;opacity:.5;
  background-image:radial-gradient(rgba(242,240,233,.09) 1px, transparent 1px);
  background-size:11px 11px;
  -webkit-mask-image:linear-gradient(var(--a-dot-angle,200deg),#000,transparent 62%);
          mask-image:linear-gradient(var(--a-dot-angle,200deg),#000,transparent 62%);
}
.card .art .tagbig{
  position:absolute;left:20px;bottom:11px;
  font-family:'Anton',sans-serif;text-transform:uppercase;
  font-size:22px;line-height:.9;letter-spacing:.02em;
  color:transparent;-webkit-text-stroke:1.1px rgba(242,240,233,.24);
  max-width:64%;
}
.card .art svg{position:absolute;color:rgb(var(--a-tint,201,247,58));transition:opacity .3s ease,transform .5s ease;}
.card .art .m1{
  right:var(--a-m1-x,-22px);bottom:var(--a-m1-y,-30px);
  width:var(--a-m1-size,120px);opacity:var(--a-m1-op,.5);
  transform:rotate(var(--a-m1-rot,0deg));
}
.card .art .m2{
  left:var(--a-m2-x,20px);top:var(--a-m2-y,-14px);
  width:var(--a-m2-size,64px);opacity:var(--a-m2-op,0);
  transform:rotate(var(--a-m2-rot,0deg));
}
.card:hover .art .m1{opacity:calc(var(--a-m1-op,.5) + .3);transform:translate(-8px,-8px) rotate(calc(var(--a-m1-rot,0deg) - 5deg));}
.card:hover .art .stripe{transform:skewX(var(--a-skew,-18deg)) translateX(190%);}

/* ---------- The octagon as interface ----------
   The mark is an octagon but every surface was a plain rectangle. Cards now
   carry the same cut corners as the logo. A border cannot follow a
   clip-path, so the hairline is an inset shadow instead — that does follow
   it — and the page-level border is zeroed out. */
.card,a.card{
  border:0 !important;
  box-shadow:inset 0 0 0 1px var(--hair);
  clip-path:polygon(11px 0, calc(100% - 11px) 0, 100% 11px, 100% calc(100% - 11px),
                    calc(100% - 11px) 100%, 11px 100%, 0 calc(100% - 11px), 0 11px);
  transition:box-shadow .18s ease,transform .18s ease;
}
.card:hover,a.card:hover{box-shadow:inset 0 0 0 1px rgba(201,247,58,.55);}
/* our own writing keeps its volt edge, now on the same inset hairline */
.card.orig{box-shadow:inset 0 0 0 1px rgba(201,247,58,.5);}
.card.orig:hover{box-shadow:inset 0 0 0 1px var(--volt);}

/* A volt notch that draws itself into the cut corner on hover. */
.card{position:relative;}
.card::before{
  content:'';position:absolute;top:0;right:0;width:11px;height:11px;z-index:3;
  background:linear-gradient(225deg, var(--volt) 0 50%, transparent 50%);
  opacity:0;transform:translate(-2px,2px);
  transition:opacity .2s ease,transform .2s ease;pointer-events:none;
}
.card:hover::before{opacity:1;transform:none;}

/* Back to top — the mark itself, floated in once a page gets long. */
.gm-top{
  position:fixed;right:22px;bottom:22px;z-index:55;
  width:46px;height:46px;display:flex;align-items:center;justify-content:center;
  background:rgba(12,14,10,.86);backdrop-filter:blur(8px);
  border:1px solid rgba(201,247,58,.4);cursor:pointer;padding:0;
  opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .25s ease,transform .25s ease,visibility .25s,background .15s,border-color .15s;
  clip-path:polygon(11px 0, calc(100% - 11px) 0, 100% 11px, 100% calc(100% - 11px),
                    calc(100% - 11px) 100%, 11px 100%, 0 calc(100% - 11px), 0 11px);
}
.gm-top.on{opacity:1;visibility:visible;transform:none;}
.gm-top svg{width:22px;height:22px;transition:transform .2s;}
.gm-top:hover{background:var(--volt);border-color:var(--volt);}
.gm-top:hover svg{transform:rotate(-22.5deg);}
.gm-top:hover svg path{stroke:var(--black);}
@media(max-width:700px){.gm-top{right:14px;bottom:14px;width:42px;height:42px;}}

/* ---------- Depth ----------
   The page was flat near-black with two big radial gradients, which band
   visibly on cheaper panels. A fixed grain layer breaks the banding up and
   gives the black some tooth. It sits above the content but under the nav
   and any dialog, and never takes a pointer event. The noise is generated
   by an inline SVG filter — no image request. */
body::after{
  content:'';position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.038;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px;
}

/* The cage: two 45-degree hairline grids behind the page headers, faded out
   downward so they read as texture rather than as a pattern. Same motif the
   betting league uses, so the two sites feel related. ::after is unused on
   these elements site-wide, so nothing gets clobbered. */
.hero,.masthead{position:relative;}
.hero::after,.masthead::after{
  content:'';position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:
    repeating-linear-gradient(45deg, rgba(201,247,58,.05) 0 1px, transparent 1px 17px),
    repeating-linear-gradient(-45deg, rgba(201,247,58,.05) 0 1px, transparent 1px 17px);
  -webkit-mask-image:radial-gradient(ellipse 90% 78% at 50% 0%, #000 22%, transparent 76%);
          mask-image:radial-gradient(ellipse 90% 78% at 50% 0%, #000 22%, transparent 76%);
}
/* The header's own content must stay above the cage — but only the content.
   Every header also holds a decorative mark that positions itself absolutely
   (the Utah map, the big octagon watermark, the homepage octagon field), and
   this rule used to force all of them back into normal flow: same specificity
   as the pages' own rules, but site.css loads later, so it won. That put a
   tall block in the middle of every header. Invisible at opacity .055, and
   very visible on Utah, whose map is a real graphic — it pushed the heading
   and intro clean off a phone screen.
   Decorative children are all aria-hidden, so that is the line. :where()
   keeps the selector at its original specificity, so nothing else in the
   cascade shifts. */
.hero > *:not(:where([aria-hidden="true"])),
.masthead > *:not(:where([aria-hidden="true"])){position:relative;z-index:1;}

/* ---------- Fight-week pulse ----------
   A live chip in the nav, driven by /assets/fightpulse.js. Quiet when the
   next card is days out, volt on the day, red and breathing once the first
   bell goes. Hidden on narrow screens where the nav row is already tight. */
.fw-chip{
  display:flex;align-items:center;gap:9px;flex-shrink:0;margin-left:auto;
  padding:7px 13px;border:1px solid var(--hair);
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--steel);white-space:nowrap;
  transition:border-color .2s,color .2s,background .2s;
}
.fw-chip .bout{color:var(--bone);opacity:.75;}
/* Not in the nav. The ticker running directly above the bar already scrolls
   the full matchup, so repeating it here spent 174px saying the same thing
   twice — and that overflow is what pushed the links onto two lines. The nav
   chip keeps the countdown, which the ticker doesn't give you at a glance.
   Done in CSS rather than left to the script's own overflow detection: that
   check only fires when the row actually overflows, and a wrapping row never
   does, so it was silently never firing. */
nav .fw-chip .bout{display:none;}
/* set by the script when the nav row would otherwise overflow */
.fw-chip.fw-compact .bout{display:none;}
.fw-chip:hover{border-color:var(--volt);color:var(--volt);}
.fw-chip.fw-today{border-color:rgba(201,247,58,.55);color:var(--volt);}
.fw-chip.fw-today .bout{color:var(--bone);opacity:1;}
.fw-chip.fw-live{border-color:var(--red);color:var(--red);background:rgba(255,75,62,.09);}
.fw-chip.fw-live .bout{color:var(--bone);opacity:1;}
.fw-chip.fw-live .dot{
  width:7px;height:7px;flex-shrink:0;background:var(--red);
  transform:rotate(22.5deg);animation:fwPulse 1.5s ease-in-out infinite;
}
@keyframes fwPulse{0%,100%{opacity:1;}50%{opacity:.25;}}
@media(max-width:1100px){.fw-chip{display:none !important;}}

/* ---------- Motion on state change ----------
   Paired with /assets/ui.js. Lists arrive item by item instead of blinking
   into place, and the active-tab fill travels rather than teleporting. */
/* The resting state is VISIBLE, and the entrance is described entirely inside
   the keyframes with a `both` fill.

   It used to be the other way round: the element sat at opacity:0 and only an
   animation reaching its end could reveal it. That makes content depend on an
   animation succeeding, and when one didn't, the whole Utah roster — 71 rows,
   correctly rendered, correct count above them — was invisible until a filter
   click rebuilt the list. Nothing was broken except that the reveal never
   arrived, which is the worst kind of bug: the page looks empty and the data
   is right there.

   `backwards` fill still holds the from-state through the stagger delay, so
   the effect is identical when it runs. When it doesn't run for any reason —
   animation stripped, element never painted, a quirk nobody predicted — the
   row is simply visible, because that is now what the rule says. */
.gm-stagger{animation:gmStagger .36s cubic-bezier(.2,.7,.3,1) both;animation-delay:var(--i,0ms);}
@keyframes gmStagger{from{opacity:0;transform:translateY(9px);}to{opacity:1;transform:none;}}

.gm-tabs{position:relative;}
.gm-tabs .gm-ind{
  position:absolute;left:0;top:0;width:0;height:0;z-index:0;opacity:0;
  background:var(--volt);pointer-events:none;
  transition:left .3s cubic-bezier(.2,.7,.3,1),top .3s cubic-bezier(.2,.7,.3,1),
             width .3s cubic-bezier(.2,.7,.3,1),height .3s cubic-bezier(.2,.7,.3,1),opacity .2s ease;
}
/* The tabs sit above the pill; the active one drops its own fill and lets the
   travelling pill supply it (only once the script has taken over). Descendant
   selectors, not child: the fighters page groups its filters into rows, and a
   child combinator silently stopped matching there — leaving both the pill and
   the button's own fill drawn, one on top of the other. */
.gm-tabs button{position:relative;z-index:1;}
.gm-hasind button.on{background:transparent;border-color:var(--volt);}

/* ---------- Modal entrance ----------
   The fighter card used to appear with no transition at all. Keyframes, not
   a transition: the modal goes display:none -> flex, and a transition will
   not run off that change. Each animation ends at the element's natural
   state, so reduced motion (which kills animation outright) still shows a
   correctly positioned, fully opaque dialog. */
.fmodal.on{animation:gmModalIn .2s ease;}
@keyframes gmModalIn{from{opacity:0;}}
.fmodal.on .box{animation:gmBoxIn .28s cubic-bezier(.2,.7,.3,1);}
@keyframes gmBoxIn{from{transform:translateY(14px) scale(.985);}}

@media(prefers-reduced-motion:reduce){
  /* never let a disabled animation strand content mid-entrance */
  .gm-stagger{opacity:1;transform:none;animation:none;}
}

/* ---------- Readable on a phone ----------
   A count of every text node on a 375px screen found 96 of them at 13px or
   smaller, much of it body copy rather than labels. The mono micro-type is
   part of the brand and stays; what moves is the prose you actually read,
   plus a floor under the very smallest labels so nothing lands under 11px.
   Desktop is untouched. */
@media(max-width:700px){
  body{font-size:16.5px;}
  .card p,a.card p,.rail .ritem p,.lead .dek,.dek,.note,
  .lg .bd,.lg .bd p,.divnote,.pick p,.issue p{font-size:16px;line-height:1.6;}
  .card h3,a.card h3{font-size:21px;}
  .rk .meta,.fr .meta{font-size:11.5px;}
  .card .time,a.card .t,.rail .ritem .t{font-size:11.5px;}
  .eyebrow,.mono-tag,.sechead .mono-tag{font-size:11.5px;}
  footer,footer .fine{font-size:12.5px;line-height:2;}
  .adwrap .lbl{font-size:11px;}
  /* The tape's column labels ("vs", "odds", "line via") sat at 10px. The
     homepage defines these as `.tape .row .mid`, so this has to match that
     specificity — a media query adds none, and the shorter selector lost. */
  .tape .row .mid{font-size:11.5px;}
}

/* ---------- Skip link ----------
   Off-screen until focused, so keyboard users can jump the six nav links
   instead of tabbing them on every page. */
.gm-skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  padding:12px 18px;background:var(--volt);color:var(--black);
  font-family:'JetBrains Mono',monospace;font-size:12px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;
}
.gm-skip:focus{left:0;}

/* ---------- Keyboard focus ----------
   Site-wide so every page shows where the keyboard is, not just the
   homepage. Mouse users never see it (:focus-visible, not :focus). */
a:focus-visible,button:focus-visible,input:focus-visible,
select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--volt);outline-offset:3px;
}

/* ---------- Reduced motion ---------- */
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;}.eyebrow,h1,.dek{opacity:1;transform:none;}.hero .bigmark path{stroke-dashoffset:0;}.reveal{opacity:1;transform:none;}}

/* ---------- Original-article treatment ----------
   Our own writing gets a volt edge and a badge so it never reads like
   another wire rewrite. Cards opt in with .orig; the badge works inline
   next to any category label. */
.card.orig{border-color:rgba(201,247,58,.5);}
.card.orig:hover{border-color:var(--volt);}
.origbadge{
  display:inline-block;vertical-align:middle;margin-left:8px;padding:2.5px 8px;
  background:var(--volt);color:var(--black);
  font-family:'JetBrains Mono',monospace;font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;font-weight:700;white-space:nowrap;
}
.rail .ritem .origbadge{margin-left:6px;}

/* ---------- Marquee pause control ----------
   Hover already pauses the ticker; this gives touch users (and anyone who
   just wants it to hold still) an explicit control. */
.marquee{position:relative;}
.marquee .pausebtn{
  position:absolute;right:8px;top:50%;transform:translateY(-50%);z-index:3;
  width:28px;height:28px;display:flex;align-items:center;justify-content:center;
  background:rgba(12,14,10,.85);border:1px solid var(--hair);color:var(--steel);
  cursor:pointer;font-size:10px;line-height:1;padding:0;
}
.marquee .pausebtn:hover,.marquee .pausebtn:focus-visible{color:var(--volt);border-color:var(--volt);outline:none;}
.marquee.paused .track{animation-play-state:paused !important;}

/* V7 — a load that failed, rather than a spinner that never stops.
   Set by the watchdog in /assets/fsdata.js when a container is still marked
   aria-busy long after any real read would have finished. */
.fs-stalled{border:1px dashed var(--hair);padding:38px 24px;text-align:center;}
.fs-stalled-h{font-family:'Anton',sans-serif;text-transform:uppercase;letter-spacing:.02em;
  font-size:20px;color:var(--bone);margin:0 0 8px;}
.fs-stalled-p{font-size:14.5px;line-height:1.6;color:var(--steel);margin:0 auto 18px;max-width:34em;}
.fs-retry{font-family:'JetBrains Mono',monospace;font-size:11.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;cursor:pointer;
  padding:11px 24px;color:var(--black);background:var(--volt);border:2px solid var(--volt);}
.fs-retry:hover{background:transparent;color:var(--volt);}
