/* ============================================
   MADE BY WACHO — global stylesheet
   Yellow #FFD40D / Ink #232323
   Norca Rough (display) + TASA Explorer (UI)
   Tight spacing · squared corners · high contrast
   ============================================ */

/* ---- Fonts ----
   Norca Rough is served locally from /fonts.
   Fragment Mono is loaded from Google Fonts (see index.html). */

@font-face {
  font-family: "Norca Rough";
  src: url("fonts/NorcaRough.woff2") format("woff2"),
       url("fonts/NorcaRough.otf") format("opentype");
  font-weight: 400;
  font-display: swap;
}

:root {
  --yellow: #ffd40d;
  --ink: #232323;
  --font-display: "Norca Rough", "Arial Black", "Archivo Black", sans-serif;
  --font-ui: "Fragment Mono", ui-monospace, "Courier New", monospace;
  --gutter: 20px;
  --row-gap: 4px;
  --cursor: url("assets/cursor.svg") 3 1, auto;
}

html,
button,
a {
  cursor: var(--cursor);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  border-radius: 0;
}

::selection {
  background: var(--ink);
  color: var(--yellow);
}

html {
  background: var(--yellow);
}

body {
  background: var(--yellow);
  color: var(--ink);
  font-family: var(--font-ui);
  text-transform: uppercase;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;
  padding-top: 13px;
}

/* ---- Masthead ----
   Spans the same column as the table (full width on mobile,
   inset and capped on desktop); fitText() sizes it edge-to-edge. */

.masthead {
  width: 100%;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14.55vw; /* refined at runtime by fitText() */
  letter-spacing: -0.07em;
  line-height: 0.78;
  text-align: center;
  white-space: nowrap;
  text-box: trim-both cap alphabetic;
  user-select: none;
  margin-inline: auto;
}

/* ---- Stack: accordions pinned above the ticker ---- */

.stack {
  display: flex;
  flex-direction: column;
  gap: 48px;
}

/* ---- Accordions ---- */

.accordions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 var(--gutter);
}

/* Inset layout (Figma node 48:668) on desktop only: masthead and table
   share one centered column, capped for ultrawide screens. The footline
   stays full-bleed. Mobile keeps the full-width gutter. */
@media (min-width: 768px) {
  .masthead,
  .accordions {
    width: min(58vw, 1040px);
    padding-inline: 0;
    margin-inline: auto;
  }
}

.accordion {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.accordion__header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 4px 0;
  background: var(--ink);
  color: var(--yellow);
  border: none;
  font-family: var(--font-ui);
  font-size: clamp(12px, 1.1vw, 16px);
  letter-spacing: 0.35em;
  text-transform: uppercase;
  text-align: left;
  cursor: var(--cursor);
  overflow: clip; /* crop the oversized arrow to the bar, like the Figma frame */
}

.accordion__header:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: -3px;
}

.accordion__title {
  flex: 1 0 0;
  min-width: 1px;
  padding-left: 4px;
}

.accordion__count {
  white-space: nowrap;
  padding-right: 4px;
}

/* Full-size circular arrow cropped by the short bar (Figma node 34:129).
   The box reserves horizontal space in flow (so it never overlaps the
   count) without stretching the bar; the SVG is absolutely centered. */
.chevron-box {
  flex: 0 0 auto;
  align-self: stretch;
  position: relative;
  width: clamp(32px, 3.4vw, 48px);
  margin-right: clamp(8px, 2vw, 28px);
  pointer-events: none;
}

.chevron {
  position: absolute;
  top: 50%;
  left: 50%;
  width: clamp(32px, 3.4vw, 48px);
  height: clamp(32px, 3.4vw, 48px);
  transform: translate(-50%, -50%);
  transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
}

.accordion.is-open .chevron {
  transform: translate(-50%, -50%) rotate(180deg);
}

/* ---- Accordion body / item rows ----
   Grow/shrink is animated with the grid-template-rows 0fr→1fr technique:
   the outer element is a one-row grid whose row animates, the inner
   wrapper (min-height: 0, overflow: hidden) gets squeezed. */

.accordion__body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 360ms cubic-bezier(0.4, 0, 0.2, 1);
}

.accordion.is-open .accordion__body {
  grid-template-rows: 1fr;
}

.accordion__body-inner {
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--row-gap);
  padding-top: var(--row-gap);
}

.item {
  display: flex;
  flex-direction: column;
  width: 100%;
  transition: background-color 200ms ease;
}

.item__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 8px 0 4px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--font-ui);
  font-weight: 400; /* Fragment Mono ships regular only */
  font-size: clamp(12px, 1.1vw, 16px);
  color: var(--ink);
  text-transform: uppercase;
  text-align: left;
  cursor: var(--cursor);
  transition: color 200ms ease, background-color 200ms ease;
}

.item__row:hover,
.item__row:focus-visible {
  background: var(--ink);
  color: var(--yellow);
  outline: none;
}

/* Open item: black fill, yellow type, inverted tags (Figma node 34:271) */
.item.is-open {
  background: var(--ink);
}

.item.is-open .item__row {
  color: var(--yellow);
}

.item.is-open .item__content {
  color: var(--yellow);
}

.item.is-open .item__tags {
  background: var(--yellow);
  color: var(--ink);
}

.item__name {
  flex: 1 0 0;
  min-width: 1px;
  padding-left: 4px;
}

/* Type column: fixed em width so values align across rows (mono font) */
.item__type {
  width: 9em;
  flex: 0 0 auto;
  letter-spacing: 0.15em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.item__version {
  white-space: nowrap;
  padding-right: 4px;
}

.item__content {
  display: grid;
  grid-template-rows: 0fr;
  width: 100%;
  transition: grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

.item.is-open .item__content {
  grid-template-rows: 1fr;
}

.item__content-inner {
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 16px;
  padding: 0 4px;
  transition: padding 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

.item.is-open .item__content-inner {
  padding: 4px 4px 8px;
}

/* Left block: description on top, tags pinned to the card bottom */
.item__body {
  flex: 1 0 0;
  min-width: 1px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.item__body .item__tags {
  margin-top: auto;
}

/* Featured media: idle VHS loop underneath, real reveal clip fades in
   on hover. Both layers fill the frame; only the hover layer animates
   opacity, so the base loop keeps playing quietly beneath it. */
.item__media {
  position: relative;
  flex: 0 0 auto;
  width: clamp(120px, 22%, 200px);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  margin: 0;
}

.item__media-base,
.item__media-hover {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.item__media-hover {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 260ms ease;
}

.item__media:hover .item__media-hover {
  opacity: 1;
}

/* No hover on mobile: skip the crossfade, show the reveal clip as the
   default (matches script.js pausing the idle base loop underneath). */
@media (hover: none), (max-width: 640px) {
  .item__media-hover {
    opacity: 1;
    transition: none;
  }
}

.item__description {
  flex: 1 0 0;
  min-width: 1px;
  font-size: 14px;
  line-height: 1.45;
  text-transform: none;
}

.item__tags {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
  background: var(--ink);
  color: var(--yellow);
  font-weight: 400; /* Fragment Mono ships regular only */
  font-size: clamp(14px, 1.7vw, 24px);
  letter-spacing: -0.03em;
  white-space: nowrap;
  transition: color 200ms ease, background-color 200ms ease;
}

.item__link {
  color: inherit;
  text-decoration: none;
}

.item__link:hover {
  text-decoration: underline;
}

/* ---- About panel (Figma node 48:1156) ----
   Black plate: roles + flipped meta on the left, GIF flush right. */

.about {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 24px;
  width: 100%;
  min-height: clamp(260px, 27vw, 381px);
  background: var(--ink);
  color: var(--yellow);
}

.about__info {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 23px 25px 18px 25px;
  flex: 1 1 0;
  min-width: 0;
  container-type: inline-size;
}

/* Sized off the info column's own width (not the viewport), so the
   longest word ("OVERTHINKER") always fits — the column's share of the
   page varies with the inset layout and the media split next to it. */
.about__roles {
  font-size: clamp(22px, 12cqw, 56px);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1.15;
}

.about__meta {
  margin-top: auto;
  display: flex;
  justify-content: space-between;
  max-width: 305px;
  transform: scaleY(-1);
  font-size: 12px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.about__media {
  flex: 0 0 auto;
  width: min(480px, 46%);
  object-fit: cover;
  display: block;
}

@media (max-width: 640px) {
  .about {
    flex-direction: column;
    gap: 0;
  }

  .about__info {
    padding: 16px 16px 20px;
  }

  .about__media {
    width: 100%;
    max-height: 340px;
  }
}

/* ---- Footer ticker ----
   Infinite marquee, full-bleed. JS clones the phrase enough times to
   cover the widest viewport, then duplicates the whole group once so
   a -50% translate loops seamlessly with no gap or jump. */

.ticker {
  overflow: hidden;
  width: 100%;
  user-select: none;
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker-scroll 26s linear infinite;
}

.ticker__group {
  display: flex;
  flex-shrink: 0;
}

.ticker__item {
  font-family: var(--font-display);
  font-size: clamp(28px, 4.2vw, 60px);
  letter-spacing: -0.02em;
  line-height: 0.9;
  white-space: nowrap;
  padding-right: 0.6em;
}

@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}


/* ---- Click knock effect ----
   Short strokes bursting out from the click point; purely visual.
   Colors alternate ink/yellow so it reads on both surfaces. */

.knock {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 999;
  pointer-events: none;
}

.knock span {
  position: absolute;
  left: -1.5px;
  top: -6px;
  width: 3px;
  height: 12px;
  background: var(--ink);
  animation: knock-line 320ms cubic-bezier(0.2, 0.6, 0.3, 1) forwards;
}

.knock span:nth-child(even) {
  background: var(--yellow);
}

@keyframes knock-line {
  from {
    opacity: 1;
    transform: rotate(var(--a)) translateY(-8px) scaleY(1);
  }
  to {
    opacity: 0;
    transform: rotate(var(--a)) translateY(-22px) scaleY(0.4);
  }
}

@media (prefers-reduced-motion: reduce) {
  .accordion__body,
  .item__content,
  .item__content-inner,
  .chevron {
    transition: none;
  }

  .ticker__track {
    animation: none;
  }

  .knock {
    display: none;
  }
}

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

@media (max-width: 640px) {
  .page {
    gap: 24px;
  }

  /* Break "WACHO" onto its own line; fitText() sizes the widest line */
  .masthead {
    line-height: 0.82;
  }

  .masthead__break {
    display: block;
  }

  .stack {
    gap: 28px;
  }

  :root {
    --gutter: 10px;
  }

  .accordion__header .chevron {
    width: 36px;
    height: 36px;
  }

  .item__content-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  /* Media stacks full-width above the description */
  .item__media {
    order: -1;
    width: 100%;
    aspect-ratio: 4 / 3;
  }
}

@media (max-width: 480px) {
  .item__type {
    width: auto;
    max-width: 7em;
    letter-spacing: 0.05em;
    margin-right: 8px;
  }
}
