/* VG Team
   Two colours from the logo, one typeface, and the logo's three shapes
   (ring, V, bar) as the only ornaments. Blue appears only on PINK+ data. */

@font-face {
  font-family: "Archivo";
  src: url("../assets/fonts/archivo-latin-wdth-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo";
  src: url("../assets/fonts/archivo-latin-ext-wdth-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --ink: #000;
  --paper: #fff;
  --ink-soft: #5c5c5c;      /* secondary text on paper */
  --paper-soft: #a6a6a6;    /* secondary text on ink */
  --rule-on-paper: #d4d4d4;
  --rule-on-ink: #2e2e2e;
  --signal: #0098d8;        /* PINK+ CTF blue, used on its data only */

  --pad: clamp(20px, 5vw, 88px);
  --font: "Archivo", "Arial Nova", Arial, "Helvetica Neue", sans-serif;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-in-out: cubic-bezier(.7, 0, .2, 1);

  /* Logo proportions, measured from the artwork: bar = 1/9 of the mark. */
  --bar: clamp(8px, 0.9vw, 14px);
}

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--ink);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.125rem;
  line-height: 1.5;
  font-stretch: 100%;
  color: var(--paper);
  background: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 4px;
}

::selection { background: var(--signal); color: #fff; }

.sprite { position: absolute; }

.skip-link {
  position: fixed;
  left: var(--pad);
  top: 12px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--paper);
  color: var(--ink);
  font-weight: 700;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

.wrap {
  width: 100%;
  padding-inline: var(--pad);
}

.on-paper {
  --fg: var(--ink);
  --bg: var(--paper);
  --soft: var(--ink-soft);
  --rule: var(--rule-on-paper);
  background: var(--bg);
  color: var(--fg);
}

.on-ink {
  --fg: var(--paper);
  --bg: var(--ink);
  --soft: var(--paper-soft);
  --rule: var(--rule-on-ink);
  background: var(--bg);
  color: var(--fg);
}

.section-title {
  font-stretch: 125%;
  font-weight: 800;
  font-size: clamp(1.75rem, 3.4vw, 3.25rem);
  line-height: 1;
  letter-spacing: -0.01em;
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px var(--pad);
  color: #fff;
  mix-blend-mode: difference; /* reads on both ink and paper sections */
  pointer-events: none;
}
.site-header a { pointer-events: auto; }
.site-header.is-hidden { transform: translateY(-100%); }
.site-header:focus-within { transform: none; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s, visibility .3s;
}
.is-past-hero .brand { opacity: 1; visibility: visible; }

.brand__mark { width: 30px; height: 30px; fill: currentColor; }

.brand__name,
.footer-brand__name {
  font-stretch: 125%;
  font-weight: 900;
  font-size: .8125rem;
  letter-spacing: .26em;
  text-transform: uppercase; /* the logotype is set in capitals */
}

.site-nav {
  display: flex;
  gap: clamp(16px, 2.4vw, 32px);
  margin-left: auto;
  font-size: .9375rem;
  font-weight: 600;
}
.site-nav a {
  text-decoration: none;
  padding-block: 6px;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 2px no-repeat;
  transition: background-size .25s var(--ease-out);
}
.site-nav a:hover,
.site-nav a:focus-visible { background-size: 100% 2px; }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  background: var(--ink);
}

.hero__stage {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 460px;
  overflow: hidden;
  isolation: isolate;
  background: var(--ink);
}

/* White disc that grows out of the logo's ring as the page scrolls. */
.hero__portal {
  position: absolute;
  inset: 0;
  background: var(--paper);
  clip-path: circle(0 at 50% 42%);
}

/* White artwork blended with "difference": it turns black wherever the
   disc has passed, so the lockup inverts along the disc's edge. */
.hero__content {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #fff;
  mix-blend-mode: difference;
}

.lockup {
  --m: clamp(150px, min(32vh, 46vw), 330px); /* mark size */
  display: grid;
  justify-items: center;
  margin-top: -3vh;
}

.mark {
  width: var(--m);
  height: var(--m);
  overflow: visible;
}
.mark__v,
.mark__bar { fill: currentColor; }
.mark__ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 60;
}

.wordmark {
  margin-top: calc(var(--m) * .06);
  font-stretch: 125%;
  font-weight: 900;
  font-size: calc(var(--m) * .2);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}
.wordmark__clip {
  display: flex;
  overflow: hidden;
  padding-block: .08em;
}
.wordmark__l { display: block; margin-right: .3em; }
.wordmark__l--gap { margin-right: .85em; }
.wordmark__l:last-child { margin-right: 0; }

.lockup__rule {
  display: block;
  width: calc(var(--m) * 1.11);
  height: max(3px, calc(var(--m) * .022));
  margin-top: calc(var(--m) * .1);
  background: currentColor;
}

.hero__meta {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px 24px;
  flex-wrap: wrap;
  padding: 0 var(--pad) clamp(20px, 4vh, 40px);
  font-size: .9375rem;
  font-weight: 500;
}
.hero__meta a {
  font-weight: 700;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}

/* ---------- Result ---------- */

.result {
  padding-block: clamp(72px, 14vh, 180px) clamp(72px, 12vh, 160px);
}

.display {
  font-stretch: 125%;
  font-weight: 900;
  font-size: clamp(2.25rem, 9vw, 10rem);
  line-height: .93;
  letter-spacing: -0.02em;
}
.display__line {
  display: block;
  overflow: hidden;
  padding-bottom: .06em;
}
.display__line > span { display: block; }

.result__body {
  display: grid;
  gap: 32px;
  justify-items: start;
  max-width: 34rem;
  margin-top: clamp(40px, 7vh, 88px);
  margin-left: auto;
  margin-right: clamp(0px, 8vw, 160px);
  font-size: clamp(1.125rem, 1.35vw, 1.375rem);
}

.result__links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
}

/* The box keeps its hover size at rest (the negative margin lines the text up
   with the paragraph), so filling it moves nothing around it. */
.bar-link {
  --inset: 14px;
  display: inline-block;
  margin-inline: calc(var(--inset) * -1);
  padding: 8px var(--inset);
  font-weight: 700;
  text-decoration: none;
  /* The fill is pinned to --fg: with currentColor it would follow the text to
     --bg on hover and the whole link would vanish into the page. */
  background: linear-gradient(var(--fg), var(--fg)) var(--inset) 100% / calc(100% - var(--inset) * 2) 4px no-repeat;
  transition: background-size .3s var(--ease-out), background-position .3s var(--ease-out), color .3s;
}
.bar-link:hover,
.bar-link:focus-visible {
  color: var(--bg);
  background-position: 0 100%;
  background-size: 100% 100%;
}

/* ---------- Replay ---------- */

.replay__stage {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: clamp(16px, 3vh, 40px);
  height: 100vh;
  height: 100svh;
  min-height: 520px;
  padding-block: clamp(72px, 11vh, 120px) clamp(20px, 4vh, 48px);
  border-top: 1px solid var(--rule);
}

.replay__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 48px;
}
.replay__hint {
  max-width: 34rem;
  color: var(--soft);
  font-size: 1rem;
}

.replay__grid {
  display: grid;
  grid-template-columns: minmax(250px, .85fr) minmax(0, 2.4fr);
  gap: clamp(24px, 4vw, 72px);
  min-height: 0;
}

.readout {
  align-self: end;
  padding-bottom: 30px; /* sits on the chart's baseline */
  font-variant-numeric: tabular-nums;
}
.readout__score {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 12px;
  font-stretch: 125%;
  font-weight: 900;
  font-size: clamp(3.25rem, 7.4vw, 8rem);
  line-height: .9;
  letter-spacing: -0.03em;
}
.readout__unit {
  flex-basis: 100%; /* always under the number, so it never jumps as the score widens */
  margin-top: 8px;
  line-height: 1.2;
  font-stretch: 100%;
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: 0;
  color: var(--soft);
}
.readout__step {
  margin-top: clamp(14px, 2.4vh, 28px);
  color: var(--soft);
  font-size: 1rem;
}
.readout__name {
  margin-top: 2px;
  font-stretch: 112%;
  font-weight: 800;
  font-size: clamp(1.375rem, 2.2vw, 2rem);
  line-height: 1.15;
  overflow-wrap: anywhere;
}
.readout__meta {
  margin-top: 4px;
  color: var(--soft);
  font-size: 1rem;
  min-height: 1.5em;
}

.chart {
  position: relative;
  min-height: 0;
  min-width: 0;
}
.chart__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  font-variant-numeric: tabular-nums;
  touch-action: pan-y;
}
.chart__grid { stroke: var(--rule); stroke-width: 1; }
.chart__base { stroke: var(--fg); stroke-width: 2; }
.chart__day { stroke: var(--fg); stroke-width: 1; stroke-dasharray: 2 4; }
.chart__top { stroke: var(--signal); stroke-width: 1.5; stroke-dasharray: 6 5; }
.chart__label { fill: var(--soft); font-size: 12px; font-weight: 500; }
.chart__label--day { fill: var(--fg); font-size: 13px; font-weight: 700; }
.chart__label--top { fill: var(--fg); font-weight: 700; }
.chart__bar-base { fill: var(--fg); }
.chart__bar-cap { fill: var(--signal); }
.chart__pointer { fill: var(--fg); }

/* ---------- Solves ---------- */

.solves {
  padding-block: clamp(72px, 12vh, 150px) clamp(88px, 14vh, 180px);
  border-top: 1px solid var(--rule);
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px clamp(18px, 2.4vw, 34px);
  margin-top: clamp(28px, 5vh, 48px);
}
.filter {
  appearance: none;
  border: 0;
  padding: 8px 0 10px;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 4px no-repeat;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: background-size .25s var(--ease-out);
}
.filter__count {
  margin-left: 6px;
  color: var(--soft);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.filter:hover { background-size: 100% 2px; }
.filter[aria-pressed="true"] { background-size: 100% 4px; }

.solves__summary {
  margin-top: 18px;
  color: var(--soft);
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
}

.solve-table {
  width: calc(100% + 24px);
  margin: 20px -12px 0;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  text-align: left;
}
.solve-table th {
  padding: 10px 12px;
  color: var(--soft);
  font-size: .875rem;
  font-weight: 500;
  white-space: nowrap;
}
.solve-table td {
  padding: 13px 12px;
  border-top: 1px solid var(--rule);
  vertical-align: baseline;
}
.solve-table tbody tr { transition: background-color .12s, color .12s; }
.solve-table tbody tr:hover { background: var(--fg); color: var(--bg); }
.solve-table tbody tr:hover td { border-top-color: var(--fg); }
.solve-table tbody tr:hover .solve__soft,
.solve-table tbody tr:hover .solve__sub { color: inherit; }

.col-n { width: 4.5ch; }
.col-pts { text-align: right; }
.solve__n,
.solve__soft { color: var(--soft); }
.solve__name { font-stretch: 108%; font-weight: 700; }
.solve__sub {
  display: none;
  color: var(--soft);
  font-size: .875rem;
  font-weight: 400;
  font-stretch: 100%;
}
.solve__time { white-space: nowrap; }
.solve__pts { text-align: right; font-weight: 800; }

/* ---------- Roster ---------- */

.roster {
  padding-block: clamp(88px, 15vh, 190px) clamp(72px, 12vh, 150px);
}
.roster__note {
  max-width: 34rem;
  margin-top: 14px;
  color: var(--soft);
}

.members {
  margin-top: clamp(48px, 9vh, 104px);
  border-bottom: 1px solid var(--rule);
}
.member {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 32px;
  padding-block: clamp(24px, 4.5vh, 52px);
  border-top: 1px solid var(--rule);
}
.member__name {
  font-stretch: 125%;
  font-weight: 900;
  font-size: clamp(3rem, 11.5vw, 12rem);
  line-height: .9;
  letter-spacing: -0.03em;
}
.member__facts {
  font-size: clamp(1rem, 1.3vw, 1.25rem);
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}
.member__facts strong { color: var(--fg); font-weight: 700; }

/* ---------- Footer ---------- */

.site-footer {
  padding-block: 36px 44px;
  border-top: 1px solid var(--rule);
  font-size: .9375rem;
}
.site-footer__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 40px;
}
.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.footer-brand__mark { width: 40px; height: 40px; fill: currentColor; }
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin-right: auto;
}
.footer-links a {
  font-weight: 600;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}
.site-footer__fine { color: var(--soft); }

/* ---------- Scripted layout ---------- */

/* The scroll tracks only exist when the script is running. */
html:not(.js) .replay { display: none; }

/* ---------- Motion ---------- */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  .site-header { transition: transform .35s var(--ease-out); }

  /* Scroll tracks: the stage pins while the track scrolls past. */
  .js .hero { height: 230vh; height: 230svh; }
  .js .hero__stage { position: sticky; top: 0; }

  .js .replay { height: 520vh; height: 520svh; }
  .js .replay__stage { position: sticky; top: 0; }

  /* Load sequence: V wipes down, bar shoots out, ring closes around them,
     then the wordmark rises and the rule extends. */
  .mark__v {
    clip-path: inset(-2px -2px 100% -2px);
    animation: wipe-down .7s var(--ease-in-out) .25s forwards;
  }
  .mark__bar {
    transform-box: fill-box;
    transform-origin: 0 50%;
    transform: scaleX(0);
    animation: grow-x .45s var(--ease-in-out) .75s forwards;
  }
  .mark__ring {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    opacity: 0;
    animation: draw-ring 1.15s cubic-bezier(.65, 0, .25, 1) 1.05s forwards;
  }
  .wordmark__l {
    transform: translateY(120%);
    animation: rise .7s var(--ease-out) forwards;
  }
  .wordmark__l:nth-child(1) { animation-delay: 1.55s; }
  .wordmark__l:nth-child(2) { animation-delay: 1.60s; }
  .wordmark__l:nth-child(3) { animation-delay: 1.65s; }
  .wordmark__l:nth-child(4) { animation-delay: 1.70s; }
  .wordmark__l:nth-child(5) { animation-delay: 1.75s; }
  .wordmark__l:nth-child(6) { animation-delay: 1.80s; }
  .lockup__rule {
    transform: scaleX(0);
    animation: grow-x .7s var(--ease-in-out) 2s forwards;
  }
  .hero__meta,
  .site-nav {
    opacity: 0;
    animation: fade-in .7s ease 2.4s forwards;
  }

  /* Headline: lines rise out of their own baselines once, on arrival. */
  .js .display__line > span {
    transform: translateY(105%);
    transition: transform .9s var(--ease-out);
  }
  .js .display__line:nth-child(2) > span { transition-delay: .09s; }
  .js .display__line:nth-child(3) > span { transition-delay: .18s; }
  .js .display.is-in .display__line > span { transform: none; }
}

@keyframes wipe-down { to { clip-path: inset(-2px); } }
@keyframes grow-x { to { transform: scaleX(1); } }
@keyframes draw-ring {
  from { stroke-dashoffset: 1; opacity: 1; }
  to { stroke-dashoffset: 0; opacity: 1; }
}
@keyframes rise { to { transform: none; } }
@keyframes fade-in { to { opacity: 1; } }

/* ---------- Small screens ---------- */

@media (max-width: 820px) {
  .replay__grid {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    gap: 14px;
  }
  .readout {
    align-self: start;
    padding-bottom: 0;
  }
  .readout__score { font-size: clamp(2.75rem, 13vw, 4.5rem); }
  .readout__unit { flex-basis: auto; margin-top: 0; }
  .readout__step { margin-top: 8px; }
  .readout__name { font-size: 1.25rem; }
  .readout__step,
  .readout__meta,
  .replay__hint { font-size: .9375rem; }
  .replay__stage { padding-top: 68px; }

  .result__body { margin-right: 0; }
}

@media (max-width: 720px) {
  .col-cat,
  .col-by,
  .col-time,
  .solve__cat,
  .solve__by,
  .solve__time { display: none; }
  .solve__sub { display: block; }
  .solve-table td { padding-block: 11px; }
  .site-nav { font-size: .875rem; }
  .brand__name { display: none; }
}

@media (max-height: 620px) and (min-width: 821px) {
  .replay__hint { display: none; }
}
