@font-face {
  font-family: "Rodchenko";
  src: url("../public/fonts/rodchenko.woff2") format("woff2"),
       url("../public/fonts/rodchenko.ttf") format("truetype");
  font-display: swap;
}

:root {
  --paper: #F2EDE0;
  --card: #FAF6EC;
  --ink: #17150F;
  --red: #D6301C;
  --blue: #2E5F7A;
  --ochre: #C89B5F;
  --rule: rgba(23, 21, 15, 0.25);
  --cut: #F7F1E1;
  --hair: rgba(23, 21, 15, 0.28);
  --display: Rodchenko, Oswald, "Arial Narrow", sans-serif;
  --body: "Golos Text", "Helvetica Neue", sans-serif;
  --mono: "PT Mono", monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  line-height: 1.45;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}
body::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  z-index: 9;
}

.wrap { width: 100%; max-width: 1060px; margin: 0 auto; padding: 0 20px; }
.topbar { height: 10px; background: var(--red); }

/* ---------- masthead: one header — wordmark left, date right ---------- */
.mast { padding-top: 18px; }
.titleline {
  display: flex; justify-content: space-between; align-items: center;
  /* one row always — on narrow screens the pieces scale down instead of wrapping */
  gap: clamp(8px, 2vw, 12px); flex-wrap: nowrap;
  border-bottom: 3px solid var(--ink);
  padding: 0 0 12px;
}
.slovo {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(20px, 5.4vw, 48px);
  line-height: 1;
}
.slovo .wtf { font-size: 0.58em; color: var(--red); }
.datebox { display: flex; align-items: center; gap: clamp(4px, 1.2vw, 8px); margin-left: auto; }
.date {
  font-family: var(--mono);
  font-size: clamp(9px, 2.8vw, 13px);
  letter-spacing: clamp(0.05em, 0.2vw, 0.14em);
  text-transform: uppercase;
  color: var(--red);
  white-space: nowrap;
}
/* the date itself opens the archive — a text button matching the chevrons' height */
.datebtn {
  display: flex; align-items: center;
  height: clamp(24px, 7vw, 30px);
  padding: 0 clamp(6px, 1.8vw, 16px);
  border: 2px solid var(--ink);
  background: transparent;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.datebtn:hover { background: var(--red); border-color: var(--red); }
.datebtn:hover .date { color: var(--paper); }
.datebtn:active { transform: translateY(1px); }
/* pre-launch: date shows, archive doesn't open — reads as plain text */
.datebtn[disabled] { pointer-events: none; border-color: transparent; }
.navbtn {
  width: clamp(24px, 7vw, 30px); height: clamp(24px, 7vw, 30px); flex: 0 0 auto;
  display: grid; place-items: center;
  border: 2px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font-size: clamp(8px, 2.3vw, 10px);
  line-height: 1;
  padding: 0;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.navbtn:hover { background: var(--red); border-color: var(--red); color: var(--paper); }
.navbtn:active { transform: translateY(1px); }
.navbtn[disabled] { opacity: 0.3; cursor: default; pointer-events: none; }

/* ---------- hero stage ---------- */
.stage {
  position: relative;
  margin-top: 16px;
  /* --head-cap = the head's horizontal budget: 46% of the wrap content box
     (max-width 1060px − 2×20px padding → 469.2px ceiling, 46vw − 18.4px below
     the max). If .wrap geometry or the 46% share changes, update this too. */
  --head-cap: min(46vw - 18.4px, 469.2px);
  /* stage = head + 14px headroom, shrunk on short windows: with the 16px
     margin above and the sheet's 30px margin below, the figurine keeps an
     even 30px of air to the masthead rule and the sheet rule at every size
     (tall hats used to cross the rule when 56svh undercut the head) */
  --stage-h: min(56svh, calc(var(--head-cap) + 14px));
  height: var(--stage-h);
}
.head {
  position: absolute;
  left: 0; bottom: 0;
  width: min(var(--head-cap), calc(var(--stage-h) - 14px));
  aspect-ratio: 1;
  z-index: 2;
  cursor: pointer;
}
.head img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  filter: drop-shadow(2px 0 0 var(--cut)) drop-shadow(-2px 0 0 var(--cut))
          drop-shadow(0 2px 0 var(--cut)) drop-shadow(0 -2px 0 var(--cut))
          drop-shadow(1px 0 0 var(--hair)) drop-shadow(-1px 0 0 var(--hair))
          drop-shadow(0 1px 0 var(--hair)) drop-shadow(0 -1px 0 var(--hair))
          drop-shadow(9px -11px 0 rgba(23, 21, 15, 0.15)); /* casts UP — nothing below the ground line */
}
.head img.open { opacity: 0; }
.head.talking img.open { opacity: 1; }
.head.talking img.closed { opacity: 0; }

.wedge {
  position: absolute;
  /* tip tucks at 30% — deep enough that outfits whose silhouette narrows at
     mouth height (ushanka hood, parka) never show paper between head and red */
  left: 30%;
  /* ends at the content edge — same side padding as every other element */
  right: 0;
  top: 9%;
  height: 58%;
  background: var(--red);
  clip-path: polygon(0 34%, 100% 0, 100% 100%, 0 66%);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 5% 0 20%;
}
/* ---------- scenery: seeded silhouette skyline behind everything ---------- */
.scenery {
  position: absolute;
  inset: 0; /* silhouettes stand on the stage floor — the tick ruler runs just below */
  z-index: 0;
  pointer-events: none;
  color: var(--ink);
  /* one flat distant-city tone: overlapping silhouettes union instead of
     stacking darker, because the opacity sits on the group */
  opacity: 0.18;
}
.scenery svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.word {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--paper);
  line-height: 0.92;
  text-align: center;
  letter-spacing: 0.015em;
  /* never break inside a word — the autofit shrinks instead */
  overflow-wrap: normal;
  word-break: keep-all;
}

/* ---------- info sheet ---------- */
.sheet {
  display: grid;
  grid-template-columns: 1fr 1fr 1.5fr;
  gap: 22px;
  margin-top: 30px;
}
.cell { border-top: 2px solid var(--ink); padding-top: 8px; }
.lbl {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(23, 21, 15, 0.62);
  margin-bottom: 6px;
}
.val { font-size: 19px; font-weight: 600; }
.val.mono { font-family: var(--mono); font-weight: 400; font-size: 17px; color: var(--blue); }
.val.note { font-size: 15.5px; font-weight: 400; }

/* ---------- controls ---------- */
.controls {
  display: flex; gap: 12px; align-items: stretch; flex-wrap: wrap;
  margin: 26px 0 40px;
}
.controls button { cursor: pointer; }
#btnPlay {
  font-family: Oswald, var(--display), sans-serif;
  font-weight: 600;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border: 2px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  padding: 12px 22px;
  transition: background 0.12s, border-color 0.12s;
}
#btnPlay:hover { background: var(--red); border-color: var(--red); color: var(--paper); }
#btnPlay:active { transform: translateY(1px); }
#btnPlay[disabled] { opacity: 0.35; cursor: default; pointer-events: none; }
.speed { display: flex; border: 2px solid var(--ink); }
.speed button {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 0 14px;
  transition: background 0.12s, color 0.12s;
}
.speed button + button { border-left: 2px solid var(--ink); }
.speed button:hover { color: var(--red); }
.speed button.on { background: var(--ink); color: var(--paper); }
.speed button.on:hover { color: var(--paper); }
/* ---------- pre-launch ---------- */
.pre { margin: 60px 0 80px; position: relative; overflow: hidden; }
.pre-box { border: 3px solid var(--ink); padding: 40px 28px; text-align: center; position: relative; z-index: 1; }
.pre-big {
  font-family: var(--display);
  font-weight: 700; text-transform: uppercase;
  font-size: clamp(38px, 8vw, 84px);
  line-height: 0.95;
}
.pre-big .red { color: var(--red); }
.pre-sub { margin-top: 14px; font-family: var(--mono); font-size: 13px; letter-spacing: 0.08em; }

/* ---------- calendar (архив) ---------- */
.cal {
  position: fixed; inset: 0;
  z-index: 8;
  background: var(--paper);
  overflow-y: auto;
}
.cal-inner { max-width: 680px; padding-top: 28px; padding-bottom: 48px; }
.cal-head {
  display: flex; justify-content: space-between; align-items: center;
  border-bottom: 3px solid var(--ink);
  padding-bottom: 12px;
}
.cal-title {
  font-family: var(--display);
  font-weight: 700; text-transform: uppercase;
  font-size: 32px; line-height: 1;
}
.cal-month {
  display: flex; justify-content: space-between; align-items: center;
  margin: 20px 0 14px;
}
.cal-mtitle {
  font-family: var(--display);
  font-weight: 700; text-transform: uppercase;
  font-size: 20px;
  letter-spacing: 0.06em;
}
.cal-dow {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(23, 21, 15, 0.55);
  text-align: center;
  margin-bottom: 6px;
}
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.c-day {
  min-height: 58px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  border: 1px solid var(--rule);
  font-family: var(--mono);
  color: var(--ink);
  background: transparent;
  padding: 5px 6px;
  text-align: left;
}
.c-num { font-size: 10px; line-height: 1; opacity: 0.6; }
.c-word {
  font-size: 10px; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: break-word;
}
.c-day svg { margin: auto; opacity: 0.45; }
.c-blank { border: 0; min-height: 0; }
.c-void { border-color: rgba(23, 21, 15, 0.1); color: rgba(23, 21, 15, 0.25); }
.c-open { cursor: pointer; transition: background 0.1s, color 0.1s; }
.c-open:hover { background: var(--ink); color: var(--paper); }
.c-open:hover .c-num { opacity: 0.7; }
.c-today { background: var(--red); color: var(--paper); border-color: var(--red); }
.c-today .c-num { opacity: 0.85; }
.c-today:hover { background: var(--red); color: var(--paper); }
.c-view { outline: 2px solid var(--ink); outline-offset: -2px; }
.c-locked { color: rgba(23, 21, 15, 0.45); cursor: default; }

/* ---------- footer ---------- */
/* footer.wrap out-specifies .wrap's `padding: 0 20px`, which was silently
   zeroing every padding-top set on the bare `footer` selector */
footer.wrap {
  position: relative; /* anchors .foot-tip + the content-box rule */
  margin-top: auto;
  padding: 44px 20px 26px;
  /* 1fr | auto | 1fr — equal side tracks keep the made-with block anchored to
     the column's true center even as the rotating word animates its width */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "title made za";
  align-items: baseline;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(23, 21, 15, 0.55);
}
/* the rule spans the CONTENT box (like the masthead's), not the padding box —
   otherwise the text reads as randomly inset against a wider line */
footer.wrap::before {
  content: "";
  position: absolute;
  top: 0; left: 20px; right: 20px;
  border-top: 1px solid var(--rule);
}
footer .day-title { grid-area: title; justify-self: start; cursor: help; }
footer .day-title .dt-day { color: var(--red); }
footer .made { grid-area: made; justify-self: center; white-space: nowrap; }
/* no day title on screen (specials, pre-launch, «Рано!») — made-with takes the
   left edge instead of anchoring to an empty center */
footer.wrap:has(.day-title[hidden]) { grid-template-areas: "made . za"; }
footer.wrap:has(.day-title[hidden]) .made { justify-self: start; }
/* negative margin swallows the trailing letter-space so the «!» glyph, not
   its tracking, lands on the content edge */
footer .za { grid-area: za; justify-self: end; margin-right: -0.14em; color: var(--red); cursor: help; }
/* typewriter word swap: chars punched in one-by-one behind a red block caret */
footer .rot {
  display: inline-block;
  vertical-align: bottom;
  white-space: nowrap;
  overflow: hidden;
  transition: width 0.28s ease;
  cursor: help;
}
/* hover tips: english translation on an ink chip, red wedge pointer (JS sets left/top) */
footer .foot-tip {
  position: absolute;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--paper);
  padding: 5px 8px 4px;
  font-size: 10px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
footer .foot-tip::after {
  content: '';
  position: absolute;
  top: 100%; left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--red);
  border-bottom-width: 0;
}
footer .foot-tip.show { opacity: 1; }
footer .rot .caret {
  display: inline-block;
  width: 0.62ch;
  height: 1.1em;
  background: var(--red);
  vertical-align: text-bottom;
}
footer .rot .caret.idle { animation: caret-blink 1.06s steps(1) infinite; }
@keyframes caret-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  footer .rot { transition: none; }
  footer .rot .caret.idle { animation: none; }
  footer .foot-tip { transition: none; }
}

/* ---------- mobile: word banner on top, head below ----------
   Red banner carries the word across the content width (same side padding as
   everything else); the head tucks up into its bottom edge so the shout still
   reads as his. */
@media (max-width: 720px) {
  .mast { padding-top: 12px; }
  .stage {
    height: auto;
    margin-top: 12px;
  }
  .wedge {
    position: relative;
    left: auto; right: auto;
    margin: 0;
    height: 38vw;
    max-height: 190px;
    clip-path: polygon(0 10%, 100% 0, 100% 78%, 0 100%);
    padding: 3% 6% 6%;
  }
  /* skyline stays in the head zone — never pokes above the banner */
  .stage .scenery { top: auto; height: 52vw; max-height: 260px; }
  /* proverbs and long toasts get a taller plaque */
  .wedge.long { height: 52vw; max-height: 260px; }
  .head {
    position: relative;
    width: 56vw; max-width: 280px;
    margin: -9vw auto 0;
  }
  .sheet { grid-template-columns: 1fr; gap: 16px; margin-top: 22px; }
  .val { font-size: 18px; }
  .controls { margin: 22px 0 34px; }
  #btnPlay { flex: 1 1 100%; }
  .speed { width: 100%; }
  .speed button { flex: 1; padding: 12px 0; }
  .cal-title { font-size: 26px; }
  .c-day { min-height: 50px; padding: 4px 5px; }
  .c-word { font-size: 9px; }
  /* footer folds to two rows: edges share the top line, made-with centers
     below — no ornament between them; the caret is the row's accent. Generous
     gap above the made-with line (Mete's eye: more air than the 26px below) */
  footer.wrap {
    grid-template-columns: auto auto;
    grid-template-areas: "title za" "made made";
    row-gap: 36px;
  }
  /* no day title: made-with left + За Леону! right on ONE line (Mete's call).
     The pair only clears 375px when the rotation lands on дисциплина if the
     footer type clamps down a hair at the narrow end (masthead-style vw clamp;
     back to 11px by ~400px wide) */
  footer.wrap:has(.day-title[hidden]) {
    grid-template-areas: "made za";
    font-size: clamp(9.5px, 2.75vw, 11px);
  }
}
