/* HUUUH? "Blocks" design (main page + /p player). Layout and type only: every colour is a variable
 * from css/theme.css (the Neon Alley palette). Three flat blocks carry the structure:
 * b1 = the meme, b2 = the sound, b3 = send it. Sticker buttons: thick outline + hard shadow that collapses on press.
 * Fonts (SIL OFL 1.1, Basic Latin subsets): Anton (caption), Archivo Black (labels), DM Sans (UI text). */
@font-face { font-family: "Anton"; src: url("../fonts/anton/anton-latin.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Archivo Black"; src: url("../fonts/archivo-black/archivo-black-latin.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "DM Sans"; src: url("../fonts/dm-sans/dm-sans-latin.woff2") format("woff2"); font-weight: 100 1000; font-display: swap; }
:root { --r: 14px; --sticker: 4px; }
* { box-sizing: border-box; }
/* The root is the meme pink: iOS Safari tints the status bar / top toolbar and the rubber-band
 * areas from it (and from <meta name=theme-color>, which repeats --b1). */
html { -webkit-text-size-adjust: 100%; background: var(--b1); }
body { margin: 0; min-height: 100dvh; background: transparent; color: var(--b1-ink); font-family: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
a { color: inherit; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
:focus-visible { outline: 3px solid var(--b1-ink); outline-offset: 3px; }
.blk.n :focus-visible { outline-color: var(--b2-fg); }
.blk.w :focus-visible { outline-color: var(--b3-ink); }

/* ---- the meme: video with the in-video caption (the only HUUUH?) */
.stage { position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: #000; cursor: pointer;
  border-radius: var(--r); box-shadow: 0 0 0 3px var(--b1-ink), 6px 6px 0 3px var(--b1-ink); }
.stage video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* The clip's first frame underneath the (transparent) video: it shows whenever iOS Safari's video
 * layer is empty (before the first play, right after a seek), and while the warm-up hides the video. */
.stage .still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; z-index: 0; pointer-events: none; }
.stage video { z-index: 1; background: transparent; }
.stage video.warmhide { opacity: 0; }
.caption {
  position: absolute; margin: 0; pointer-events: none; white-space: nowrap; z-index: 2;
  font-family: "Anton", Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif;
  font-weight: 400; line-height: 1; letter-spacing: 0.02em; text-transform: uppercase; color: #fff; font-size: 48px;
  text-shadow:
    0.065em 0 0 #000, -0.065em 0 0 #000, 0 0.065em 0 #000, 0 -0.065em 0 #000,
    0.046em 0.046em 0 #000, -0.046em 0.046em 0 #000, 0.046em -0.046em 0 #000, -0.046em -0.046em 0 #000,
    0.06em 0.025em 0 #000, -0.06em 0.025em 0 #000, 0.06em -0.025em 0 #000, -0.06em -0.025em 0 #000,
    0.025em 0.06em 0 #000, -0.025em 0.06em 0 #000, 0.025em -0.06em 0 #000, -0.025em -0.06em 0 #000, 0 0 0.04em #000;
}
.caption.top { top: 7%; } .caption.bottom { bottom: 7%; }
.caption.left { left: 5%; text-align: left; } .caption.right { right: 5%; text-align: right; }
.caption.center { left: 0; right: 0; text-align: center; }
.caption span { opacity: 0; } .caption span.on { opacity: 1; }
#voice { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* ---- blocks */
.blk { padding: 20px max(16px, env(safe-area-inset-right)) 20px max(16px, env(safe-area-inset-left)); }
.blk.y { padding-top: max(20px, env(safe-area-inset-top)); }
.blk.n { padding-bottom: max(20px, env(safe-area-inset-bottom)); }
/* mobile: the black sound block runs to the bottom, so a short view never shows the pink root */
.blocks { min-height: 100dvh; display: flex; flex-direction: column; }
.blocks > .blk.n { flex: 1 0 auto; }
.blk.y { background: var(--b1); color: var(--b1-ink); }
.blk.n { background: var(--b2); color: var(--b2-fg); }
.blk.w { background: var(--b3); color: var(--b3-ink); }

/* ---- sticker buttons (content and actions) */
.clips button, #play, .act, .preset, #plain, .make a { --bd: var(--b1-ink); border: 3px solid var(--bd); border-radius: var(--r); box-shadow: var(--sticker) var(--sticker) 0 var(--bd);
  transition: transform .08s, box-shadow .08s, background-color .12s, color .12s; }
.clips button:active, #play:active, .act:active, .preset:active, #plain:active, .make a:active { transform: translate(var(--sticker), var(--sticker)); box-shadow: 0 0 0 var(--bd); }
.row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; row-gap: 16px; margin-top: 24px; reading-flow: flex-visual; }
.clips { display: flex; gap: 8px; }
.clips button { width: 44px; height: 44px; padding: 0; background: var(--chip); color: var(--chip-fg); font: 400 17px/1 "Archivo Black", sans-serif; }
.clips button[aria-pressed="true"] { background: var(--chip-on); color: var(--chip-on-fg); }
#play { height: 52px; padding: 0 22px; background: var(--play); color: var(--play-fg); display: inline-flex; align-items: center; gap: 10px; font: 400 18px/1 "Archivo Black", sans-serif; text-transform: uppercase; }
#play svg { width: 16px; height: 16px; }
.is-playing #play { background: var(--play-on); color: var(--play-on-fg); }
#status { margin: 12px 0 0; color: var(--err); font-weight: 600; font-size: 14px; }
#status:empty { display: none; }

/* ---- tabs: a segmented switch (views), deliberately unlike the sticker chips (content) */
.tabs { display: flex; width: max-content; gap: 0; padding: 3px; margin: 0 auto 20px; border: 2px solid var(--b2-fg); border-radius: 999px; }
.tabs button { height: 38px; padding: 0 22px; border: 0; border-radius: 999px; background: transparent; color: var(--b2-fg); font: 700 15px/1 "DM Sans", sans-serif; letter-spacing: 0; transition: background-color .15s, color .15s; }
.tabs button[aria-selected="true"] { background: var(--b2-fg); color: var(--b2); }
.tabs button:focus-visible { outline-offset: 4px; }

/* ---- moods: a perfect grid (equal cells, fixed columns, Original spans the row) */
.blk.n .preset, .blk.n #plain { --bd: var(--mood-bd); }
.presets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 12px; padding: 0 var(--sticker) var(--sticker) 0; }
.preset { width: 100%; height: 52px; padding: 0 8px; display: flex; align-items: center; justify-content: center; text-align: center; white-space: nowrap; overflow: hidden;
  background: var(--mood); color: var(--mood-fg); font: 400 15px/1 "Archivo Black", sans-serif; text-transform: uppercase; letter-spacing: 0.01em; }
.preset .emo { display: none; }
.preset[data-preset="original"] { grid-column: 1 / -1; }
.preset[aria-pressed="true"] { background: var(--on); color: var(--on-fg); }
/* easter egg: Disgusted, tapped again, turns into BLAAAH (a short pop, same cell) */
.preset.egg-pop { animation: egg-pop 420ms cubic-bezier(.2,.9,.3,1.4); }
@keyframes egg-pop { 0% { transform: scale(1); } 30% { transform: scale(1.08) rotate(-2deg); } 60% { transform: scale(.97) rotate(1deg); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .preset.egg-pop { animation: none; } }

/* ---- sliders */
.slider { display: block; margin-bottom: 12px; color: var(--b2-fg); }
.slider .top { display: flex; justify-content: space-between; align-items: baseline; font: 400 16px/1 "Archivo Black", sans-serif; text-transform: uppercase; }
.slider output { font: 600 14px/1 "DM Sans", sans-serif; color: var(--b2-mute); font-variant-numeric: tabular-nums; }
.slider .ends { display: flex; justify-content: space-between; color: var(--b2-mute); font-size: 13px; margin-top: -4px; }
.slider input[type=range] { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 48px; margin: 0; background: transparent; touch-action: pan-y; --fa: 50%; --fb: 50%; }
.slider input[type=range]::-webkit-slider-runnable-track { height: 14px; border: 3px solid var(--b2-fg); border-radius: 999px; background: linear-gradient(90deg, var(--b2) var(--fa), var(--on) var(--fa), var(--on) var(--fb), var(--b2) var(--fb)); }
.slider input[type=range]::-moz-range-track { height: 8px; border: 3px solid var(--b2-fg); border-radius: 999px; background: var(--b2); }
.slider input[type=range]::-moz-range-progress { background: transparent; }
.slider input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 28px; height: 28px; margin-top: -10px; border-radius: 50%; background: var(--b2-fg); border: 3px solid var(--b2); box-shadow: 0 0 0 2px var(--b2-fg); }
.slider input[type=range]::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: var(--b2-fg); border: 3px solid var(--b2); }
.slider input[type=range]:focus-visible { outline: 3px solid var(--b2-fg); outline-offset: 2px; border-radius: 10px; }
.slider input[type=range]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--b2), 0 0 0 6px var(--b2-fg); }
.slider input[type=range]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--b2), 0 0 0 6px var(--b2-fg); }
.slider-foot { display: flex; justify-content: flex-end; align-items: center; margin-top: 8px; color: var(--b2-mute); font-size: 14px; }
#plain { height: 40px; padding: 0 14px; background: var(--mood); color: var(--mood-fg); font: 400 13px/1 "Archivo Black", sans-serif; text-transform: uppercase; }

/* Main page sliders: title + track only (values are aria-valuetext on each input). */
.slider output, .slider .ends, #mode { display: none; }
.slider { margin-bottom: 6px; }

/* ---- Copy link / Download: on mobile two equal yellow stickers under the cats | Play row
 * (in the meme block); on desktop they join that row (see the desktop block). */
/* DOM order is cats, Copy link, Download, Play (the desktop row). On mobile the buttons wrap to a
 * full-width line under cats | Play; reading-flow keeps Tab in that visual order. */
.row .acts { order: 3; flex: 1 0 100%; display: flex; gap: 12px; padding: 0 var(--sticker) var(--sticker) 0; }
.act { --bd: var(--b1-ink); flex: 1; min-width: 0; height: 46px; padding: 0 8px; background: var(--b3); color: var(--b3-ink); display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: 400 15px/1 "Archivo Black", sans-serif; text-transform: uppercase; white-space: nowrap; }
.act svg { width: 18px; height: 18px; flex: none; }
.act.done { background: var(--act-done); color: var(--act-done-fg); }
.act.busy { cursor: progress; }
.foot { display: flex; justify-content: center; gap: 24px; margin-top: 24px; font-size: 14px; font-weight: 600; }
.foot a { color: var(--b3-mute); text-decoration: none; padding: 8px; }
.foot a:hover { text-decoration: underline; }

@media (min-width: 960px) {
  /* Desktop: one screen, no scroll. The meme block (video + one control row with cats, Copy link,
   * Download and Play) sits on top; the sound block below shows Moods and Tune side by side.
   * The video is sized by the viewport height: its width is the column max or whatever the height
   * leaves after the fixed rest (--rest), at 16:9. Below ~600px high it stops shrinking (400px) and the page scrolls. */
  :root {
    --colmax: 1180px;
    /* breathing room (generous): --pad top, --gap video->controls, --bgap controls->sound block,
     * --bgr gap between buttons in a row, --cgap between mood rows, --spad sound block padding */
    --pad: 24px; --gap: 24px; --bgap: 28px; --ctrl: 60px; --bgr: 18px;
    --cell: 48px; --cgap: 18px; --spad: 26px;
    --sound: calc(4 * var(--cell) + 3 * var(--cgap) + 2 * var(--spad));
    --rest: calc(var(--pad) + var(--gap) + var(--ctrl) + var(--bgap) + var(--sound) + 10px);
    --col: max(400px, min(var(--colmax), calc(100vw - 96px), calc((100dvh - var(--rest)) * 16 / 9)));
    --low: min(calc(100vw - 96px), max(var(--col), 960px));
    /* the control row never gets narrower than its contents, even under a small video */
    --ctrlw: max(var(--col), 900px);
    --side: calc((100vw - var(--ctrlw)) / 2);
  }
  .blocks { min-height: 100dvh; display: grid; background: var(--b1);
    grid-template-columns: minmax(0, 1fr) var(--col) minmax(0, 1fr); grid-template-rows: auto auto auto 1fr; }
  .blk.y, .blk.y .row, .blk.w { display: contents; }
  .stage { grid-column: 2; grid-row: 1; width: var(--col); margin-top: var(--pad); }
  .clips { grid-column: 1 / -1; grid-row: 2; justify-self: start; align-self: center; margin: var(--gap) 0 0 var(--side); }
  .clips { gap: 16px; }
  .clips button { width: 52px; height: 52px; font-size: 20px; }
  #play { grid-column: 1 / -1; grid-row: 2; justify-self: end; align-self: center; margin: var(--gap) var(--side) 0 0;
    width: 184px; height: var(--ctrl); padding: 0; justify-content: center; font-size: 21px; }
  #play svg { width: 17px; height: 17px; }
  /* Copy link / Download: yellow stickers left of Play (Play stays the big one) */
  .row .acts { order: 0; flex: none; grid-column: 1 / -1; grid-row: 2; justify-self: end; align-self: center; margin: var(--gap) calc(var(--side) + 184px + var(--bgr)) 0 0; padding: 0; gap: var(--bgr); }
  .act { --bd: var(--b1-ink); flex: none; height: 52px; padding: 0 20px; background: var(--b3); color: var(--b3-ink); font-size: 15px; }
  .act.done { background: var(--act-done); color: var(--act-done-fg); }
  .blk.w :focus-visible { outline-color: var(--b1-ink); }
  #status { grid-column: 2; grid-row: 3; margin: 8px 0 0; }
  /* sound block: Moods | Tune, no switch */
  .blk.n { grid-column: 1 / -1; grid-row: 4; margin-top: var(--bgap); padding: var(--spad) calc((100% - var(--low)) / 2);
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 64px; align-items: start; }
  .blk.n .tabs { display: none; }
  .blk.n #panel-sliders[hidden] { display: block !important; }
  /* moods: 3 equal columns, Classic spans two cells: 2 + 10 = 12, four full rows */
  .presets { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--cgap) var(--bgr); }
  .preset { height: var(--cell); font-size: 15px; }
  .preset[data-preset="original"] { grid-column: span 2; }
  /* sliders: title and track on one line */
  /* Tune: 4 slider rows + Reset, kept no taller than the 4 mood rows (so the video keeps its height) */
  .slider { display: grid; grid-template-columns: 120px minmax(0, 1fr); align-items: center; column-gap: 20px; margin: 0; height: 48px; }
  .slider .top { font-size: 16px; }
  .slider input[type=range] { height: 48px; }
  .slider-foot { margin-top: 12px; }
  #plain { height: 40px; padding: 0 18px; font-size: 13px; }
}
/* short desktop windows (< 720px high): a bit less air so the video keeps >= 400px without scrolling */
@media (min-width: 960px) and (max-height: 719px) {
  :root { --pad: 16px; --gap: 16px; --bgap: 18px; --spad: 18px; --cell: 44px; --cgap: 12px; --bgr: 14px; }
  .slider, .slider input[type=range] { height: 40px; }
  .slider-foot { margin-top: 12px; }
}
@media (min-width: 1600px) and (min-height: 1000px) {
  :root { --cell: 54px; --cgap: 20px; --colmax: 1240px; }
  .preset { font-size: 17px; }
  .slider { height: 56px; } .slider input[type=range] { height: 56px; }
  .slider .top { font-size: 18px; }
  .act { height: 56px; font-size: 17px; }
}

/* ---- share player (/p): one meme block, a big Play, a way back */
/* narrow phones (< 360px): cats + Play do not fit one line; Play wraps and spans the row */
@media (max-width: 359px) { .row #play { flex: 1 0 100%; justify-content: center; }
  .row .acts { gap: 10px; } .row .act { padding: 0 8px; gap: 6px; font-size: 13px; min-width: 0; } }
.player .blk.y { min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; padding-top: max(24px, env(safe-area-inset-top)); padding-bottom: calc(24px + env(safe-area-inset-bottom)); }
.player .inner { width: 100%; max-width: 860px; margin: 0 auto;
  /* one centred column: the video is the column width, or what the height leaves at 16:9 (no scroll),
   * never under 320px; Play is 420px or the video width if that is narrower; Make your own centred.
   * --prest: everything but the video (block padding, Play + gap, Make your own + gap, shadow). */
  --prest: calc(max(24px, env(safe-area-inset-top)) + 24px + env(safe-area-inset-bottom) + 32px + 64px + 28px + 44px + 12px);
  --pw: min(100%, max(320px, calc((100dvh - var(--prest)) * 16 / 9))); }
.player .stage { width: var(--pw); margin: 0 auto; }
.player #play { display: flex; width: min(420px, var(--pw)); max-width: none; height: 64px; margin: 32px auto 0; justify-content: center; font-size: 22px; }
.player #play svg { width: 20px; height: 20px; }
.make { margin: 28px 0 0; text-align: center; }
.make a { display: inline-flex; align-items: center; height: 44px; padding: 0 18px; background: var(--make); color: var(--make-fg); text-decoration: none; font: 400 14px/1 "Archivo Black", sans-serif; text-transform: uppercase; }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }
