/* ==========================================================================
   DOGFOOD — global stylesheet
   Everything here is document-level. All component styling lives inline in
   index.html (the <x-dc> template) or is computed in app.js.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset / document
   -------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scrollbar-color: #FF3D6E #0B1020;
  scrollbar-width: thin;
}

body {
  margin: 0;
  background: #0B1020;
  color: #E6ECFF;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

table {
  border-collapse: collapse;
}

/* --------------------------------------------------------------------------
   2. Element defaults
   -------------------------------------------------------------------------- */
a {
  color: #FF3D6E;
  text-decoration: none;
  transition: color .15s linear;
}

a:hover {
  color: #E6ECFF;
}

summary {
  list-style: none;
  cursor: pointer;
}

summary::-webkit-details-marker {
  display: none;
}

/* Solid #FF3D6E behind body copy was a glare on this dark ground. A low
   teal wash tints the run instead and leaves the type its own colour, so a
   selected paragraph stays as readable as an unselected one. */
::selection {
  background: rgba(0, 229, 208, .26);
  color: #F2F6FF;
}

::-moz-selection {
  background: rgba(0, 229, 208, .26);
  color: #F2F6FF;
}

/* --------------------------------------------------------------------------
   3. Footnotes

   Citation markers in the prose link to their entry in the reference list.
   The header is fixed at ~64px, so jump targets need clearance or they land
   underneath it. The :target rule flags which entry you landed on — the list
   is a three-column grid, so without it you arrive mid-grid with no cue.
   -------------------------------------------------------------------------- */
[id^="ref-"] {
  scroll-margin-top: 92px;
  border-left: 1px solid transparent;
  padding-left: 10px;
  margin-left: -11px;
  transition: border-color .25s linear, background .25s linear;
}

[id^="ref-"]:target {
  border-left-color: #FF3D6E;
  background: rgba(255, 61, 110, .07);
}

/* --------------------------------------------------------------------------
   4. Scrollbar (WebKit)
   -------------------------------------------------------------------------- */
::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: #0B1020;
  border-left: 1px solid #16203A;
}

::-webkit-scrollbar-thumb {
  background: #FF3D6E;
  border: 3px solid #0B1020;
}

::-webkit-scrollbar-thumb:hover {
  background: #E6ECFF;
}

::-webkit-scrollbar-corner {
  background: #0B1020;
}

/* --------------------------------------------------------------------------
   5. Keyframes — in use
   -------------------------------------------------------------------------- */

/* hero wordmark: RGB-split flicker */
@keyframes glitch {
  0%, 92% { transform: none; text-shadow: none }
  93% { transform: translate3d(-2px, 0, 0); text-shadow: 3px 0 rgba(255, 61, 110, .9), -3px 0 rgba(0, 229, 208, .55) }
  95% { transform: translate3d(2px, 0, 0); text-shadow: -4px 0 rgba(255, 61, 110, .85), 4px 0 rgba(230, 236, 255, .4) }
  97% { transform: translate3d(-1px, 0, 0); text-shadow: 2px 0 rgba(255, 61, 110, .7) }
  100% { transform: none; text-shadow: none }
}

/* hero wordmark: per-letter 3D drop-in ([data-letter]) */
@keyframes letterin {
  from { opacity: 0; transform: translate3d(0, 42%, -200px) rotateX(-70deg) }
  to { opacity: 1; transform: none }
}

/* marquee strips ([data-marquee], [data-marquee2]) */
@keyframes mq {
  from { transform: translate3d(0, 0, 0) }
  to { transform: translate3d(-50%, 0, 0) }
}

/* generic staggered entrance */
@keyframes boot {
  from { opacity: 0; transform: translateY(8px) }
  to { opacity: 1; transform: none }
}

/* wide entrance, used by the hero <h1> */
@keyframes bootw {
  from { opacity: 0; transform: translateY(24px) scale(.985) }
  to { opacity: 1; transform: none }
}

/* one-shot CRT scan on first paint */
@keyframes sweep {
  0% { transform: translateY(-30vh); opacity: .55 }
  90% { opacity: .35 }
  100% { transform: translateY(115vh); opacity: 0 }
}

/* live-status dot ([data-live]) */
@keyframes blink {
  0%, 48% { opacity: 1 }
  49%, 100% { opacity: 0 }
}

/* --------------------------------------------------------------------------
   6. Keyframes — defined but not currently referenced.
      Kept so existing markup can opt back in; safe to delete if unused.
   -------------------------------------------------------------------------- */
@keyframes spin {
  to { transform: rotate(360deg) }
}

@keyframes float {
  0%, 100% { transform: translateY(0) }
  50% { transform: translateY(-7px) }
}

@keyframes stripe {
  to { background-position: 44px 0 }
}

@keyframes drawx {
  from { transform: scaleX(0) }
  to { transform: scaleX(1) }
}

/* --------------------------------------------------------------------------
   7. Header navigation

   Desktop: a single inline row of links, right-aligned in the fixed header.
   Mobile (<= 860px): the same list becomes an off-canvas sidebar, opened by
   the burger and closed by the scrim, the close button, Escape, or picking a
   link. Open state is driven by `.is-open`, toggled from app.js state — the
   styling lives here rather than inline because the desktop/mobile split
   needs a media query.
   -------------------------------------------------------------------------- */
.dfnav-links {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.6vw, 22px);
  flex-wrap: wrap;
  justify-content: flex-end;
  font: 400 10.5px/1 'JetBrains Mono', monospace;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 8px 0;
}

/* Burger, scrim and in-drawer close button are mobile-only chrome. */
.dfnav-burger,
.dfnav-scrim,
.dfnav-close {
  display: none;
}

@media (max-width: 860px) {
  /* Roomier bar on phones: the burger is the only tap target up here, so it
     gets some air above and below. Inline styles set the base height, hence
     the !important. */
  .dfnav {
    min-height: 56px !important;
    padding-top: 10px !important;
    padding-bottom: 10px !important;
  }

  .dfnav-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 38px;
    height: 34px;
    padding: 0;
    background: transparent;
    border: 1px solid #1B2540;
    color: #E6ECFF;
    cursor: pointer;
    transition: border-color .12s linear;
  }

  .dfnav-burger:hover,
  .dfnav-burger[aria-expanded="true"] {
    border-color: #FF3D6E;
  }

  .dfnav-burger-box {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 17px;
    height: 11px;
  }

  .dfnav-burger-bar {
    display: block;
    height: 1px;
    width: 100%;
    background: #E6ECFF;
    transition: transform .18s ease, opacity .12s linear;
  }

  .dfnav-burger[aria-expanded="true"] .dfnav-burger-bar:nth-child(1) {
    transform: translateY(5px) rotate(45deg);
  }

  .dfnav-burger[aria-expanded="true"] .dfnav-burger-bar:nth-child(2) {
    opacity: 0;
  }

  .dfnav-burger[aria-expanded="true"] .dfnav-burger-bar:nth-child(3) {
    transform: translateY(-5px) rotate(-45deg);
  }

  /* Sits under the grain/scanline overlays (89-91) like the header itself. */
  .dfnav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 81;
    background: rgba(11, 16, 32, .72);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s linear;
  }

  .dfnav-scrim.is-open {
    opacity: 1;
    pointer-events: auto;
  }

  .dfnav-links {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 82;
    width: min(80vw, 300px);
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    gap: 4px;
    padding: 18px 22px calc(28px + env(safe-area-inset-bottom, 0px));
    background: #0B1020;
    border-left: 1px solid #00E5D0;
    font-size: 12px;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    transition: transform .24s cubic-bezier(.16, 1, .3, 1);
  }

  .dfnav-links.is-open {
    transform: none;
  }

  /* The links carry their own entrance animation inline; in the drawer they
     become full-width rows with a hairline rule between them. */
  .dfnav-links > a {
    padding: 15px 2px;
    border-bottom: 1px solid #131C36;
  }

  .dfnav-links > a:last-child {
    border-bottom: 0;
    margin-top: 18px;
    justify-content: center;
    padding: 14px 16px;
  }

  .dfnav-close {
    display: block;
    align-self: flex-end;
    margin-bottom: 10px;
    padding: 8px 2px;
    background: transparent;
    border: 0;
    font: 400 10.5px/1 'JetBrains Mono', monospace;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: #6B7A9E;
    cursor: pointer;
    transition: color .12s linear;
  }

  .dfnav-close:hover {
    color: #FF3D6E;
  }
}

/* Scroll lock while the drawer is open. The document scrolling element is
   <html> here, so the class goes there and body follows it. */
html.dfnav-open,
html.dfnav-open body {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Prize cards (#prizes)

   Each card carries one decorative icon parked in the empty gutter to the
   right of the amount and title. The heading block reserves that gutter with
   padding-right so the art never sits under type, and the paragraph starts
   below the art band. Tilt and offset are set per card inline; size, opacity
   and blur live here so every card scales its art the same way.
   -------------------------------------------------------------------------- */

.prize-card {
  position: relative;
  overflow: hidden;
  --prize-art: 76px;
}

.prize-card--wide {
  --prize-art: 96px;
}

/* The card is the reference, not the viewport. A one-third-width desktop card
   and a full-width phone card are roughly the same number of pixels across, so
   sizing the art off the card keeps the two views identical. The px values
   above stay as the fallback where container queries are unsupported. */
@supports (container-type: inline-size) {
  .prize-card {
    container-type: inline-size;
    --prize-art: clamp(52px, 25cqi, 78px);
  }

  .prize-card--wide {
    --prize-art: clamp(78px, 7.2cqi, 96px);
  }
}

.prize-art {
  position: absolute;
  width: var(--prize-art);
  height: var(--prize-art);
  opacity: .48;
  filter: blur(.35px);
  pointer-events: none;
}

.prize-card--wide .prize-art {
  opacity: .44;
}

.prize-head {
  padding-right: calc(var(--prize-art) + 16px);
}

.prize-card--wide .prize-head {
  padding-right: calc(var(--prize-art) + 38px);
}

/* --------------------------------------------------------------------------
   Pool allocation figure (#prizes FIG. 06)

   Two cells side by side on desktop. Once they wrap, the donut cell must take
   the whole row or it leaves a dead panel beside the chart.
   -------------------------------------------------------------------------- */
.pool-fig__chart {
  flex: 0 1 240px;
}

@media (max-width: 620px) {
  .pool-fig__chart {
    flex: 1 1 100%;
  }
}

/* --------------------------------------------------------------------------
   Submission tree (#rules "anatomy of a submission")

   73-character lines. On desktop the type shrinks just enough to fit the
   column it sits in, so the block never grows its own scrollbar. Below the
   two-column breakpoint no font size both fits and stays readable, so
   legibility wins and the block scrolls sideways on its own.
   -------------------------------------------------------------------------- */
.tree-block {
  font-size: clamp(9.4px, .95vw, 12.5px);
}

@media (max-width: 820px) {
  .tree-block {
    font-size: 12.5px;
  }
}

/* ---- Judges panel (seated) ---------------------------------------------- */
.df-jgrid { display:grid; grid-template-columns:1fr; gap:14px; list-style:none; margin:0 0 34px; padding:0; }
/* Nine headliners: three columns divide evenly, so no orphan row on desktop. */
@media (min-width:760px) { .df-jgrid { grid-template-columns:repeat(2,1fr); } }
@media (min-width:1180px) { .df-jgrid { grid-template-columns:repeat(3,1fr); } }
/* Any count that does leave one card alone on the last row: let it span instead. */
@media (min-width:760px) and (max-width:1179px) { .df-jcard:last-child:nth-child(odd) { grid-column:1 / -1; } }
@media (min-width:1180px) { .df-jcard:last-child:nth-child(3n+1) { grid-column:1 / -1; } }
.df-jcard { display:flex; flex-direction:row; border:1px solid #1B2540; background:#0B1020; overflow:hidden; transition:border-color .18s linear; }
.df-jcard:hover { border-color:#26355C; }
.df-jcard__media { flex:none; width:160px; align-self:stretch; overflow:hidden; background:#0E1428; }
@media (max-width:520px) { .df-jcard { flex-direction:column; } .df-jcard__media { width:100%; aspect-ratio:1; } }
.df-jphoto { width:100%; height:100%; object-fit:cover; filter:grayscale(1) contrast(.98); transition:filter .3s ease, transform .3s ease; }
.df-jcard:hover .df-jphoto { filter:grayscale(0) contrast(1); transform:scale(1.03); }
.df-jphoto--empty, .df-chip__photo--empty { display:grid; place-items:center; font-family:'Archivo Black',sans-serif; color:#26355C; background:#0E1428; }
.df-jphoto--empty { font-size:3rem; }
.df-jcard__body { display:flex; flex-direction:column; gap:7px; padding:16px 18px 18px; min-width:0; flex:1; }
.df-jcard__name { margin:0; font:800 16px/1.2 'Syne',sans-serif; letter-spacing:.01em; color:#E6ECFF; }
.df-jcard__meta { font:400 15px/1.3 'VT323',monospace; letter-spacing:.12em; text-transform:uppercase; color:#FF3D6E; }
.df-jcard__bio { margin:0; font:400 12px/1.8 'JetBrains Mono',monospace; color:#AEBAD6; }
.df-li { margin-top:auto; padding-top:6px; display:inline-flex; align-items:center; gap:6px; font:400 15px/1 'VT323',monospace; letter-spacing:.14em; text-transform:uppercase; color:#6B7A9E; text-decoration:none; transition:color .18s linear; }
.df-li:hover { color:#00E5D0; }
.df-panel-label { border-bottom:1px solid #1B2540; padding-bottom:8px; margin-bottom:18px; font:400 15px/1 'VT323',monospace; letter-spacing:.16em; color:#6B7A9E; }
.df-marquee { overflow:hidden; padding-block:4px; }
.df-marquee--auto { mask-image:linear-gradient(to right,transparent,black 5%,black 95%,transparent); -webkit-mask-image:linear-gradient(to right,transparent,black 5%,black 95%,transparent); }
.df-marquee__track { display:flex; gap:12px; width:max-content; }
.df-marquee--auto .df-marquee__track { animation:df-marquee 150s linear infinite; }
.df-marquee--auto:hover .df-marquee__track { animation-play-state:paused; }
@keyframes df-marquee { to { transform:translateX(-50%); } }
.df-chip { flex:0 0 148px; min-height:210px; display:flex; flex-direction:column; align-items:center; text-align:center; gap:4px; padding:12px 10px 14px; border:1px solid #1B2540; background:#0B1020; color:inherit; text-decoration:none; transition:border-color .18s linear; }
.df-chip:hover { border-color:#26355C; }
.df-chip__photo { width:96px; height:96px; object-fit:cover; margin-bottom:8px; filter:grayscale(1) contrast(.98); transition:filter .3s ease; }
.df-chip__photo--empty { font-size:2rem; }
.df-chip:hover .df-chip__photo { filter:grayscale(0) contrast(1); }
.df-chip__name { font:800 12.5px/1.25 'Syne',sans-serif; color:#E6ECFF; }
.df-chip__company { font:400 14px/1.25 'VT323',monospace; letter-spacing:.1em; text-transform:uppercase; color:#6B7A9E; }
@media (prefers-reduced-motion: reduce) {
  .df-marquee--auto { overflow-x:auto; mask-image:none; -webkit-mask-image:none; }
  .df-marquee--auto .df-marquee__track { animation:none; }
  .df-marquee--auto .df-chip[aria-hidden='true'] { display:none; }
}
