/* Self-hosted subsets: Latin + Latin-ext + Cyrillic + Cyrillic-ext.
   Cyrillic coverage is mandatory — the headline and chips are Serbian Cyrillic,
   and Serbian Latin needs č ć ž š đ from latin-ext. See fonts/README.md. */

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/oswald-600-latin.woff2') format('woff2');
  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: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/oswald-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/oswald-600-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/oswald-600-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/rubik-800-latin.woff2') format('woff2');
  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: 'Rubik';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/rubik-800-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/rubik-800-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/rubik-800-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'PT Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ptmono-400-latin.woff2') format('woff2');
  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: 'PT Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ptmono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, 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;
}
@font-face {
  font-family: 'PT Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ptmono-400-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'PT Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ptmono-400-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* ==========================================================================
   serbian.online — landing teaser "Collage"
   Implements design_handoff_landing_teaser_collage (option 2a).

   Reference canvas is 1080 x 1400. Every desktop offset below is written as
   `calc(<reference px> * var(--u))`, where --u is one reference pixel at the
   current poster size — so the numbers in this file can be diffed straight
   against the handoff. Do not replace them with pre-multiplied values.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  /* oklch is the authoring source of truth; the hex line above each is the
     sRGB fallback for engines without oklch, and is overridden where supported. */
  --ink: #100f0d;
  --paper: #f6f4ee;
  --acid: #c6e101;
  --acid: oklch(0.86 0.2 118);
  --red: #e23242;
  --red: oklch(0.6 0.21 22);
  --muted: #8e887c;
  --hairline: #4a4640;

  --display: 'Oswald', 'Arial Narrow', sans-serif;
  --latin: 'Rubik', system-ui, sans-serif;
  --mono: 'PT Mono', ui-monospace, 'Courier New', monospace;

  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* --------------------------------------------------------------------------
   Reset / page ground
   -------------------------------------------------------------------------- */

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

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

body {
  margin: 0;
  min-height: 100svh;
  background: var(--ink);
  color: var(--paper);
  /* Deliberately NOT a centering grid. An auto-sized grid column takes its
     width from the item's max-content, so the rotated note card's overflow
     would widen it past the viewport and drag the whole page off the right
     edge. The poster sizes itself on both layouts; body just holds the ground. */
  overflow-x: clip;               /* the composition never scrolls sideways */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Nothing on the page is interactive, but a link added later must not be
   browser blue. */
a { color: var(--acid); text-decoration: none; }
a:hover { color: var(--paper); }

h1, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }

/* --------------------------------------------------------------------------
   Type — shared across both layouts. Sizes and positions are per-layout.
   -------------------------------------------------------------------------- */

.wordmark {
  font-family: var(--mono);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--paper);
}
.wordmark__tld { color: var(--acid); }

.corner-label {
  font-family: var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.headline--cyr {
  font-family: var(--display);
  font-weight: 600;
  line-height: 0.81;
  text-transform: uppercase;
  color: var(--ink);              /* knocked out of the lime band */
  --rot: -7deg;                   /* must match .band--lime */
  transform: rotate(var(--rot));
}

.headline--lat {
  font-family: var(--latin);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.04em;
  color: var(--paper);
  --rot: 4deg;                    /* must match .band--red */
  transform: rotate(var(--rot));
  margin-top: 2px;;
}

.note {
  font-family: var(--mono);
  line-height: 1.5;
  background: var(--paper);
  color: var(--ink);
}

.stickers { display: flex; flex-wrap: wrap; }

.sticker {
  font-family: var(--mono);
  letter-spacing: 0.06em;
  white-space: nowrap;
}
/* Rotations are per-chip and intentionally irregular — never normalized,
   never randomized at runtime. A re-render must not reshuffle the poster. */
.sticker:nth-child(1) { --rot: -2deg; }
.sticker:nth-child(2) { --rot: 3deg; }
.sticker:nth-child(3) { --rot: -4deg; }
.sticker:nth-child(4) { --rot: 2deg; }
.sticker:nth-child(5) { --rot: -1deg; }
.sticker:nth-child(6) { --rot: 5deg; }
.sticker { transform: rotate(var(--rot)); }

.sticker--acid    { background: var(--acid);  color: var(--ink); }
.sticker--paper   { background: var(--paper); color: var(--ink); }
.sticker--red     { background: var(--red);   color: var(--paper); }  /* 4.6:1 — keep cream */
.sticker--outline { border: 1px solid var(--hairline); color: var(--paper); }

.footer {
  background: var(--acid);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.footer__inner {
  display: flex;
  justify-content: space-between;
}

/* Bands keep the default 50% 50% transform-origin — the reference depends on it,
   and pivoting anywhere else moves where the band lands. The entrance wipe is
   done with clip-path (below) precisely so it cannot disturb this. */
.band { transform: rotate(var(--rot)); clip-path: inset(0); }
.band--lime { --rot: -7deg; background: var(--acid); }
.band--red  { --rot: 4deg;  background: var(--red); }

/* ==========================================================================
   Desktop / tablet — full-bleed: the poster IS the viewport, 100% wide and
   100% tall, with no letterboxing.

   The reference is a portrait 1080x1400 canvas, so filling a landscape screen
   means the composition has to adapt rather than simply scale. It does that on
   two independent axes:

   - SIZE  (--u) scales every element and every horizontal offset. At the
     reference 1080:1400 aspect --u resolves to exactly 1, reproducing the
     handoff pixel for pixel.
   - PLACE (vertical %) distributes the blocks down the real viewport height.

   Anything whose relationship to another element is load-bearing is anchored to
   that element in --u, not to a percentage: the Cyrillic headline is pinned
   62 reference-px below the lime band's top edge exactly as in the handoff, so
   it can never drift off the band and disappear into the ground. Same for the
   Latin headline and note card against the red band.

   Every element was already anchored to an edge (wordmark left, label right,
   stickers left, footer full width), so widening the canvas spreads the collage
   apart the way a bigger sheet of paper would — only the two bands need to grow.
   ========================================================================== */

@media (min-width: 700px) {

  .poster {
    /* One reference pixel. The measure is capped at 1000px, so --u is capped at
       1000/1080; it also stays inside the viewport (48px of ground each side at
       minimum) and is capped against the viewport height so the type cannot
       outgrow the vertical room on wide, short screens. */
    --measure-max: min(1000px, calc(100vw - 96px));

    /* One reference pixel: whichever of the two caps is tighter.
       Width  — the measure never exceeds 1000px, and always leaves 48px of
                ground each side.
       Height — the composition is 1400 units tall, so capping --u at
                viewport/1400 keeps the whole poster on screen. The footer
                ("Ускоро / Uskoro / Soon") is the entire message of the page, so
                it stays above the fold rather than being scrolled to.
       Raising the height term above 1.0 buys bigger type at the cost of
       scrolling that footer out of view — see min-height below.

       The 0.52px floor is where the composition stops holding together. Small
       type has px floors (13px chips, 14px note) that do not shrink with --u,
       so past this point they dominate: the note card and the sticker row grow
       relative to everything else until there is no longer room for both them
       and the Latin headline on one line of the measure. Below the floor the
       poster keeps this size and the page scrolls, which degrades far better
       than the blocks colliding. */
    --u: max(0.52px, min(calc(var(--measure-max) / 1080), calc(100svh / 1400)));

    /* The centred measure, at the reference canvas's proportions. */
    --measure: calc(1080 * var(--u));

    /* Vertical anchors, as a fraction of the reference 1400px height. */
    --y-band-lime: 10.857%;   /* 152 / 1400 */

    /* The header line is 62/1400 down the page — but that is a fraction of the
       viewport height, while the lime band's top edge rises towards the right
       by 57.2 * --u (half the band's width * tan 7deg, at the label's x). On a
       short viewport the percentage shrinks and the rise does not, and the band
       cuts straight through "не сутра / not tomorrow". So take whichever is
       higher: the reference position, or far enough above the band to clear it.
       Both header items share the value so they stay on one line. */
    --y-header: min(4.429%, calc(var(--y-band-lime) - 57.2 * var(--u)
                                 - max(24px, calc(25 * var(--u)))));

    /* Normally 690/1400 down the viewport, but never closer to the lime band
       than the reference's own 108px gap (582 -> 690). Without the floor a wide,
       short window squeezes the two bands together until the Latin headline is
       a few px off the lime and reads as though it is sitting on it. */
    --y-band-red: max(49.286%, calc(10.857% + 538 * var(--u)));
    --y-stickers: 17.857%;    /* 250 / 1400, from the bottom */

    position: relative;
    width: 100%;

    /* Fill the viewport, but never lay the composition out in less than the
       reference's own 1400 units of height. The vertical anchors are
       percentages of this box, so on a short window they would otherwise
       compress until the sticker row climbed into the Latin headline — while
       the small type, which has a 13px floor, does not shrink to match. Below
       this height the page scrolls instead of overlapping. */
    min-height: max(100svh, calc(1400 * var(--u)));
    overflow: hidden;
    background: var(--ink);
  }

  /* Backgrounds bleed; type does not. Because the measure is centred and each
     band is symmetric about the viewport centre, every element's offset from
     its band's centre stays exactly the reference offset scaled by --u — so the
     rotated bands land on the type identically at any width, with no per-width
     correction. Widening the window only reveals more band. */
  .band--lime {
    position: absolute;
    left: calc(-60 * var(--u));
    top: var(--y-band-lime);
    width: calc(100% + 140 * var(--u));
    height: calc(430 * var(--u));
  }

  /* Width solved so the band's left edge lands at the reference 260 * --u,
     which keeps the Latin headline the reference distance from its centre. */
  .band--red {
    position: absolute;
    right: calc(-80 * var(--u));
    top: var(--y-band-red);
    width: calc(100% - 180 * var(--u));
    height: calc(120 * var(--u));
  }

  /* The measure is the reference 1080x1400 canvas: every offset below is the
     handoff's number, unchanged. */
  .stage {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: var(--measure);
    margin-inline: auto;
  }

  .stage > * { position: absolute; }

  .wordmark {
    left: calc(64 * var(--u));
    top: var(--y-header);
    font-size: max(13px, calc(15 * var(--u)));
  }

  .corner-label {
    right: calc(64 * var(--u));
    top: var(--y-header);
    font-size: max(13px, calc(14 * var(--u)));
  }

  /* Pinned to the lime band (152 -> 214), not to the viewport. */
  .headline--cyr {
    left: calc(52 * var(--u));
    top: calc(var(--y-band-lime) + 62 * var(--u));
    font-size: calc(214 * var(--u));
  }

  /* Pinned to the red band (690 -> 700). */
  .headline--lat {
    left: calc(90 * var(--u));
    top: calc(var(--y-band-red) + 10 * var(--u));
    font-size: calc(96 * var(--u));
  }

  /* Pinned to the red band (690 -> 620, i.e. above it). */
  .note {
    right: calc(74 * var(--u));
    top: calc(var(--y-band-red) - 70 * var(--u));
    /* content-box so `width` is the 250px the handoff specifies, matching the
       reference's line breaks. Under the global border-box it would be 250px
       *including* padding and the copy would wrap to five lines instead of four. */
    box-sizing: content-box;
    /* Floored for the same reason the font-size is: below about --u 0.8 the
       14px floor kicks in, and a shrinking width with a fixed font-size wraps
       this copy into a tall skinny column that grows downwards into the sticker
       row. Holding the measure keeps it the four-or-so lines it is drawn as. */
    width: max(200px, calc(250 * var(--u)));
    padding: max(12px, calc(20 * var(--u))) max(13px, calc(22 * var(--u)));
    font-size: max(14px, calc(17 * var(--u)));
    --rot: 9deg;
    transform: rotate(var(--rot));
  }

  .stickers {
    left: calc(64 * var(--u));
    bottom: var(--y-stickers);
    width: calc(700 * var(--u));
    gap: max(8px, calc(12 * var(--u)));
  }

  .sticker {
    padding: max(6px, calc(8 * var(--u))) max(10px, calc(13 * var(--u)));
    font-size: max(13px, calc(15 * var(--u)));
  }

  .footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding-block: calc(26 * var(--u));
    font-size: max(16px, calc(30 * var(--u)));
  }

  .footer__inner {
    width: var(--measure);
    margin-inline: auto;
    padding-inline: calc(64 * var(--u));
  }
}

/* ==========================================================================
   Phones — reflow rather than shrink. 214px condensed type scaled to a phone
   is unreadable, so the poster becomes a stack. Rotations, colors and layer
   order are unchanged; each band shares a grid cell with its headline so it
   tracks that headline's height automatically.
   ========================================================================== */

@media (max-width: 699.98px) {

  .poster {
    --gutter: max(24px, 6.4vw);

    position: relative;
    width: 100%;
    min-height: 100svh;
    overflow-x: clip;
    background: var(--ink);
    padding: calc(var(--gutter) * 0.9) var(--gutter) 0;

    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "mark"
      "label"
      "cyr"
      "lat"
      "note"
      "chips"
      "foot";
    align-content: start;
    row-gap: 7vw;
  }

  /* Dissolve the measure wrapper so the type and the bands are items of the
     same grid — that is what lets each band share a cell with its headline and
     track its height. On mobile the gutter already constrains the measure. */
  .stage { display: contents; }

  .wordmark     { grid-area: mark;  font-size: max(13px, 3.4vw); }

  /* The lime band's highest point is its top-RIGHT corner (rotated -7deg it
     rises by about half its width * sin7 — roughly 7vw once the band is bled
     past both gutters), and it also sits ~4vw above its own row. The label is
     right-aligned, i.e. directly over that corner, so it needs more clearance
     than the row gap alone provides or the band cuts straight through it. */
  .corner-label {
    grid-area: label;
    font-size: max(13px, 3.2vw);
    justify-self: end;
    margin-top: 3.5vw;              /* drops the label away from the wordmark */
    margin-bottom: 5vw;             /* clears the band's rotated top corner */
  }

  /* Band and headline occupy the same cell; the band is pushed out past the
     gutter on both sides so it still bleeds off the page edges. */
  .band--lime, .headline--cyr { grid-area: cyr; }
  .band--red,  .headline--lat { grid-area: lat; }

  /* The band is centred in the shared cell, so an asymmetric margin on the
     headline is what lifts the type within the band. Keep the two margins
     summing to the same total, or the whole stack shifts instead. */
  .band--lime {
    align-self: center;
    margin-inline: calc(-1 * var(--gutter) - 8vw);
    block-size: calc(100% + 6vw);
  }

  .band--red {
    align-self: center;
    margin-inline: calc(-1 * var(--gutter) - 8vw);
    block-size: calc(100% + 4vw);
  }

  .headline--cyr {
    z-index: 1;
    font-size: clamp(60px, 17.5vw, 124px);
    /* Narrow enough that "са мном" breaks to its own two lines: ПРИЧАЈ / СА / МНОМ */
    max-width: 5.2ch;
    margin-block: 3vw 11vw;         /* sits high in the lime band */
    transform: rotate(var(--rot));
  }

  .headline--lat {
    z-index: 1;
    font-size: clamp(34px, 9.8vw, 62px);
    margin-block: 1.5vw 6.5vw;      /* sits high in the red band */
    transform: rotate(var(--rot));
  }

  .note {
    grid-area: note;
    --rot: 6deg;
    /* Full width minus the gutters, pulled in slightly so the rotated corners
       stay inside the page rather than forcing a horizontal scrollbar. */
    width: calc(100% - 10px);
    justify-self: center;
    margin-block: 6vw 8vw;
    padding: max(14px, 4vw) max(14px, 4.4vw);
    font-size: max(14px, 4.1vw);
    transform: rotate(var(--rot));
  }

  .stickers {
    grid-area: chips;
    gap: 8px;
    margin-bottom: 9vw;
  }

  .sticker {
    padding: 8px 11px;
    font-size: max(13px, 3.5vw);
  }

  .footer {
    grid-area: foot;
    /* Cancel the poster's side padding so the bar bleeds edge to edge. */
    margin-inline: calc(-1 * var(--gutter));
    margin-top: auto;
    padding-block: 5vw;
    font-size: clamp(18px, 5.2vw, 22px);
  }

  .footer__inner {
    padding-inline: var(--gutter);
    gap: 8px;
  }
}

/* ==========================================================================
   Entrance — one shot, nothing loops.
   Bands wipe in along their own rotated axis, then the type rises.
   Each keyframe declares only `from`; the `to` is the element's own computed
   style, which is what makes the reduced-motion override below land exactly on
   the final state.
   ========================================================================== */

@keyframes band-wipe {
  from { transform: rotate(var(--rot, 0deg)) scaleX(0); }
}

@keyframes type-rise {
  from {
    opacity: 0;
    transform: rotate(var(--rot, 0deg)) translate3d(0, 0.7em, 0);
  }
}

.band {
  animation: band-wipe 560ms var(--ease) both;
}
.band--red { animation-duration: 520ms; animation-delay: 100ms; }

.headline--cyr,
.headline--lat,
.wordmark,
.corner-label,
.note,
.sticker,
.footer {
  animation: type-rise 480ms var(--ease) both;
}

.headline--cyr { animation-delay: 220ms; }
.headline--lat { animation-delay: 300ms; }
.note          { animation-delay: 380ms; }
.wordmark      { animation-delay: 460ms; }
.corner-label  { animation-delay: 500ms; }
.footer        { animation-delay: 540ms; }

.sticker:nth-child(1) { animation-delay: 460ms; }
.sticker:nth-child(2) { animation-delay: 500ms; }
.sticker:nth-child(3) { animation-delay: 540ms; }
.sticker:nth-child(4) { animation-delay: 580ms; }
.sticker:nth-child(5) { animation-delay: 620ms; }
.sticker:nth-child(6) { animation-delay: 660ms; }

@media (prefers-reduced-motion: reduce) {
  .poster,
  .poster * {
    animation: none !important;
  }
}
