/* ==========================================================================
   is it slop? — marker zine
   Paper, ink, three marker colours: yellow the primary action, pink the
   machine call, teal the human call. Hand-drawn is the frame and the
   ornament; every figure is set in clean type.
   ========================================================================== */

:root {
  --paper:      #FFF8EC;
  --paper-deep: #F7EBD6;
  --sheet:      #FFFDF6;
  --ink:        #111111;
  --ink-soft:   #6A5D48;   /* tinted from the paper hue, never grey */
  --rule:       rgba(17, 17, 17, .14);

  --hl-yellow:  #FFE34D;
  --hl-pink:    #FF6BAE;
  --hl-teal:    #00C7B7;

  --font-marker: "Shantell Sans", cursive;
  --font-sans:   "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --wrap: 1320px;

  --sketch-a: 255px 15px 225px 15px / 15px 225px 15px 255px;
  --sketch-b: 15px 225px 15px 255px / 255px 15px 225px 15px;

  --ease: cubic-bezier(.16, .84, .28, 1);

  /* type ramp — eight steps, each clearly distinct from its neighbour */
  --t-xs:   .85rem;
  --t-sm:   .9rem;
  --t-md:   .95rem;
  --t-base: 1rem;
  --t-body: 1.0625rem;
  --t-lg:   1.1rem;
  --t-xl:   1.3rem;
  --t-2xl:  1.6rem;

  /* fluid display steps — the marker voice scales with the viewport */
  --t-d-sm:  clamp(1.5rem, 3vw, 2.1rem);
  --t-d-md:  clamp(1.8rem, 4vw, 2.6rem);
  --t-d-lg:  clamp(1.9rem, 5vw, 3rem);
  --t-d-xl:  clamp(2.6rem, 6.4vw, 4.4rem);
  --t-d-2xl: clamp(2.7rem, 8.4vw, 5.6rem);


  /* the whole depth system: two warm brown-tinted shadows, offset and blurred */
  --shadow-key:   0 5px 14px rgba(90, 70, 25, .13);
  --shadow-sheet: 0 8px 22px rgba(90, 70, 25, .12);

  /* utility radii, for hairlines and chips the drawn frames do not cover */
  --r-hair: 2px;
  --r-tick: 3px;
  --r-util: 8px;
  --sketch-chip: 6px 10px 6px 12px;

  /* drawn marker fields: swiped top and bottom edges, stretched to the band */
  --field-y: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 200' preserveAspectRatio='none'%3E%3Cpath d='M0 13Q150 3 310 10T620 6T900 14T1200 5L1200 188Q1040 198 880 190T560 195T280 186T0 194Z' fill='%23FFE34D'/%3E%3C/svg%3E");
  --field-p: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 200' preserveAspectRatio='none'%3E%3Cpath d='M0 8Q170 18 330 9T640 13T920 4T1200 12L1200 192Q1010 183 850 193T520 187T240 196T0 187Z' fill='%23FF6BAE'/%3E%3C/svg%3E");
  --field-t: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 200' preserveAspectRatio='none'%3E%3Cpath d='M0 11Q140 4 300 12T610 5T890 12T1200 7L1200 190Q1060 196 900 187T580 193T260 188T0 195Z' fill='%2300C7B7'/%3E%3C/svg%3E");
  /* the same swiped field, unmarked: an empty slot the verdict floods */
  --field-w: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 200' preserveAspectRatio='none'%3E%3Cpath d='M0 13Q150 3 310 10T620 6T900 14T1200 5L1200 188Q1040 198 880 190T560 195T280 186T0 194Z' fill='%23F7EBD6' stroke='%23111111' stroke-width='4' stroke-dasharray='16 13' stroke-linecap='round' vector-effect='non-scaling-stroke' opacity='.85'/%3E%3C/svg%3E");
}

*, *::before, *::after { box-sizing: border-box; }

/* author `display` rules outrank the UA sheet, so `hidden` needs defending
   or a hidden panel keeps its space in the grid */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background-color: var(--paper);
  /* paper fibre */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix values='0 0 0 0 .42 0 0 0 0 .34 0 0 0 0 .16 0 0 0 .1 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23f)'/%3E%3C/svg%3E");
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.6;
  font-synthesis-weight: none;
}

h1, h2, h3 { margin: 0; font-weight: 700; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 20;
  background: var(--ink); color: var(--paper);
  padding: .7rem 1.1rem; font-weight: 600; border-radius: 0 0 var(--r-util) 0;
}
.skip:focus { left: 0; }

:where(a, button, textarea):focus-visible {
  outline: 3px solid var(--hl-teal);
  outline-offset: 3px;
  border-radius: var(--r-hair);
}

/* --- hand-drawn frame: two passes of a wobbling marker ------------------- */
.sketchy { position: relative; border: 2.5px solid var(--ink); border-radius: var(--sketch-a); }
.sketchy::after {
  content: ""; position: absolute; inset: -6px;
  border: 2px solid var(--ink); border-radius: var(--sketch-b);
  opacity: .34; pointer-events: none;
}

/* ===================== masthead ========================================== */
.masthead {
  max-width: var(--wrap); margin-inline: auto;
  padding: 1.4rem var(--pad) .6rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: .55rem; text-decoration: none; color: var(--ink); }
.brand-mark { width: 34px; height: 40px; color: var(--ink); }
.brand-word {
  font-family: var(--font-marker); font-size: var(--t-2xl); font-weight: 700;
  letter-spacing: -.02em; line-height: 1;
}
.brand-q { color: var(--hl-pink); -webkit-text-stroke: .5px var(--ink); }

.meter { display: flex; align-items: center; gap: .6rem; }
.tally { width: 60px; height: 24px; color: var(--ink); flex: none; }
.meter-text { font-family: var(--font-marker); font-size: var(--t-body); line-height: 1.2; }
.meter.is-out .meter-text { color: var(--hl-pink); -webkit-text-stroke: .4px var(--ink); }

/* ===================== the desk ========================================== */
.desk {
  max-width: var(--wrap); margin-inline: auto;
  padding: clamp(1rem, 3vw, 2.4rem) var(--pad) clamp(2rem, 4vw, 3.25rem);
  display: grid; gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 900px) {
  .desk {
    grid-template-columns: 1fr 1.02fr;
    grid-template-rows: auto 1fr;
    gap: 0 clamp(2rem, 3.4vw, 3.4rem);
    align-items: stretch;
  }
  /* the label gets a row of its own, so the sheet and the stage — the two
     shapes that actually read as panels — start on the same line */
  .sheet-label { grid-column: 1; grid-row: 1; }
  .desk-sheet  { grid-column: 1; grid-row: 2; }
  .stage       { grid-column: 2; grid-row: 2; }
  /* the placeholder carries the result's own rhythm, so swapping one for the
     other reads as a component changing state, not a different layout */
  .stage-default {
    display: flex; flex-direction: column; height: 100%;
    gap: clamp(1.6rem, 3vw, 2.2rem);
  }
  .stage-default .caution { margin-top: auto; margin-bottom: .3rem; }
  /* the passage stays in view while the findings scroll past it */
  .desk-sheet { position: sticky; top: 1.5rem; align-self: start; }
}
@media (prefers-reduced-motion: reduce) { .desk-sheet { position: static; } }
/* the paste box comes before the action on narrow screens: you cannot press
   check before you have pasted */
@media (max-width: 899px) {
  /* both columns dissolve into one flow, so the headline can introduce the
     product, the field can follow it directly, and the answer can land
     immediately under the button you just pressed */
  .desk { gap: 1.15rem; }
  .stage, .stage-default, .desk-sheet { display: contents; }
  .verdict--waiting { order: 1 }
  .notes--intro { order: 2 }
  .sheet-label { order: 3 }
  .sheet-wrap { order: 4 }
  .act { order: 5; margin-top: .3rem }
  .report { order: 6 }
  .caution { order: 7; margin-top: .6rem }
  /* the empty scales are a desktop device for holding the column's shape;
     on a phone the states are sequential, so they would only cost reach */
}

.lede {
  font-family: var(--font-marker);
  font-size: var(--t-d-xl);
  line-height: .95; letter-spacing: -.035em;
  text-wrap: balance;
}
/* the same authored swipe every other highlight uses — one way to draw a mark */
.lede em {
  font-style: normal; white-space: nowrap; padding-bottom: .06em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M3 8Q30 4 60 7T124 6T196 9Q200 22 194 34Q150 37 100 34T6 33Q0 19 3 8Z' fill='%2300C7B7'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-size: 100% .17em; background-position: 0 100%;
}

/* no artificial cap: the grid column is the measure, so the copy fills it
   instead of leaving a dead band down the middle of the page */
.sub {
  margin-top: 1.5rem;
  font-size: var(--t-lg); color: var(--ink-soft);
}

/* the action sits directly under the field it acts on, never before it */
.act {
  margin-top: clamp(1.5rem, 2.4vw, 2rem);
  display: flex; align-items: center; gap: 1.3rem; flex-wrap: wrap;
}
.act-note { font-size: var(--t-sm); color: var(--ink-soft); font-family: var(--font-marker); }

.btn {
  font-family: var(--font-marker); font-size: var(--t-xl); font-weight: 700; line-height: 1;
  color: var(--ink); background: var(--hl-yellow);
  border: 2.5px solid var(--ink); border-radius: var(--sketch-a);
  padding: .78em 1.5em; cursor: pointer; position: relative;
  transition: transform .18s var(--ease), background-color .18s var(--ease);
  box-shadow: var(--shadow-key);
}
.btn::after {
  content: ""; position: absolute; inset: -6px;
  border: 2px solid var(--ink); border-radius: var(--sketch-b);
  opacity: .38; transition: opacity .18s var(--ease);
}
.btn:hover { transform: rotate(-.8deg) translateY(-2px); }
.btn:hover::after { opacity: .7; }
.btn:active { transform: translateY(1px) rotate(0deg); }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }
.btn.is-busy { background: var(--paper-deep); }
.btn-pink { background: var(--hl-pink); }

.linky {
  font-family: var(--font-marker); font-size: var(--t-base); color: var(--ink-soft);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px;
  text-decoration-color: var(--hl-pink);
}
.linky:hover { color: var(--ink); }

/* --- the sheet ----------------------------------------------------------- */
/* .desk-sheet deliberately has no position here: it would outrank the sticky
   rule above by source order, and the mascot anchors to .sheet-wrap anyway */
.sheet-wrap { position: relative; }
.sheet-label {
  display: block; font-family: var(--font-marker); font-size: var(--t-body);
  margin-bottom: .55rem; color: var(--ink-soft);
}
.sheet { background: var(--sheet); box-shadow: var(--shadow-sheet); }
.sheet textarea {
  display: block; width: 100%; resize: vertical;
  min-height: clamp(230px, 38vh, 380px);
  border: 0; background: transparent; color: var(--ink);
  font-family: var(--font-sans); font-size: var(--t-body); line-height: 28px;
  padding: 20px 22px 8px;
  background-image: repeating-linear-gradient(to bottom, transparent 0 27px, var(--rule) 27px 28px);
  background-attachment: local; background-position: 0 20px;
}
.sheet textarea::placeholder { color: var(--ink-soft); opacity: 1; }
.sheet textarea:focus { outline: 0; }
.sheet:focus-within { box-shadow: var(--shadow-sheet), 0 0 0 3px var(--hl-teal); }
/* left-grouped so the mascot can lean on the corner without covering it */
.sheet-foot {
  display: flex; align-items: center; gap: 1.4rem;
  padding: .5rem 96px 1rem 22px; font-family: var(--font-marker);
  font-size: var(--t-md); color: var(--ink-soft);
}
/* Declared after the base rule it overrides, not before it — same specificity,
   so source order decides. A shorter field keeps the action it feeds on screen. */
@media (max-width: 899px) {
  .sheet textarea { min-height: clamp(180px, 26vh, 260px); }
}

.mascot { width: clamp(78px, 11vw, 108px); height: auto; color: var(--ink); pointer-events: none; }

/* the float rides a wrapper, so the filtered drawing inside rasterises once
   and the browser only moves the resulting layer */
.mascot-float {
  position: absolute; right: clamp(-10px, 0.5vw, 4px); bottom: clamp(-52px, -4vw, -34px);
  display: block; pointer-events: none;
  will-change: transform;
  animation: bob 5.4s ease-in-out infinite;
}
.mascot-desk { display: block; filter: none; }

@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-1.1deg); }
  50%      { transform: translateY(-8px) rotate(1.3deg); }
}

/* one face at a time */
.mascot .face { display: none; }
.mascot[data-face="wait"]  .face--wait,
.mascot[data-face="think"] .face--think,
.mascot[data-face="flat"]  .face--flat,
.mascot[data-face="shrug"] .face--shrug,
.mascot[data-face="nod"]   .face--nod { display: inline; }

/* the blink squashes each eye about its own centre */
.eye-g { transform-box: fill-box; transform-origin: center; }
.mascot.is-blink .eye-g { animation: blink .17s ease-in-out; }
@keyframes blink {
  0%, 100%  { transform: scaleY(1); }
  40%, 60%  { transform: scaleY(.06); }
}

/* a touch of lag on the pupils reads as looking rather than snapping */
.pupil { transition: transform .18s cubic-bezier(.22, 1, .36, 1); }

@media (prefers-reduced-motion: reduce) {
  .mascot-float { animation: none; }
  .mascot.is-blink .eye-g { animation: none; }
}

/* Colour means state; paper means commentary. The three highlighters keep
   their functional meanings and yellow keeps the primary action, so a caution
   reads as a note taped to the page rather than competing with the button. */
.caution {
  margin-top: clamp(2.4rem, 4vw, 2.8rem);
  font-family: var(--font-marker); font-size: var(--t-sm); line-height: 1.45;
  color: var(--ink); background: var(--paper-deep);
  padding: .8rem 1rem; border: 2px solid var(--ink);
  border-radius: var(--sketch-b); transform: rotate(-1deg);
}
/* No tape. At the size this note sits at, a torn edge is ~5px and cannot
   read, so it was ornament pretending to be material. The tilt and the drawn
   border already say "note", which is all this needs to say. */

/* ===================== report =========================================== */
.report { display: grid; gap: clamp(1.6rem, 3vw, 2.2rem); }

/* The call lands on a drawn marker field with a swiped edge — the one focal
   element must not be the only machine-straight rectangle on the page. */
.verdict {
  padding: clamp(1.8rem, 3.2vw, 2.6rem) clamp(1.1rem, 2vw, 1.8rem);
  background-repeat: no-repeat; background-size: 100% 100%;
  background-image: var(--field-y);
  text-align: center; outline: 0;
}
.verdict[data-tone="slop"]    { background-image: var(--field-p); }
.verdict[data-tone="human"]   { background-image: var(--field-t); }
.verdict[data-tone="unsure"]  { background-image: var(--field-y); }
.verdict[data-tone="waiting"] { background-image: var(--field-w); }
.verdict--waiting .verdict-call { color: var(--ink); }
.verdict--waiting .verdict-num { color: var(--ink-soft); }

/* a notice is not a verdict */
.verdict[data-kind="notice"] {
  background-image: none; background: var(--paper-deep);
  border-block: 2.5px solid var(--rule);
  padding: clamp(1.3rem, 2.4vw, 1.8rem) clamp(1.1rem, 2vw, 1.6rem);
}
.verdict[data-kind="notice"] .verdict-call { font-size: var(--t-d-sm); }
.verdict[data-kind="notice"] .verdict-num { font-size: var(--t-body); color: var(--ink-soft); }
.report[data-kind="notice"] .notes,
.report[data-kind="notice"] .caveat { display: none; }

.verdict-call {
  font-family: var(--font-marker); font-weight: 700;
  font-size: var(--t-d-xl);
  line-height: .92; letter-spacing: -.04em; text-wrap: balance;
}
.verdict-num {
  margin-top: .9rem; font-size: var(--t-body); font-weight: 600;
  font-variant-numeric: tabular-nums; text-wrap: balance;
}

/* the marker underline is a recurring device, not a one-off on the lede */
.h-how, .h-wall {
  font-family: var(--font-marker); letter-spacing: -.02em; line-height: 1.05;
  display: inline-block; padding-bottom: .14em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M3 8Q30 4 60 7T124 6T196 9Q200 22 194 34Q150 37 100 34T6 33Q0 19 3 8Z' fill='%2300C7B7'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-size: 100% .19em; background-position: 0 100%;
}



.notes { display: grid; gap: .9rem; }
.note {
  display: grid; grid-template-columns: 40px 1fr; align-items: start; gap: .7rem;
  font-family: var(--font-marker); font-size: var(--t-base); line-height: 1.45; color: var(--ink);
}
.note svg { width: 40px; height: 22px; color: var(--ink-soft); margin-top: .15rem; }
.note b { font-weight: 700; }

/* --- the measurement panel ---------------------------------------------- */

.caveat {
  padding: 1.1rem 1.3rem; background: var(--paper-deep);
  font-size: var(--t-md); line-height: 1.55;
}

/* ===================== wall ============================================= */
.wall {
  max-width: var(--wrap); margin-inline: auto;
  padding: clamp(2.6rem, 6vw, 4.5rem) var(--pad) 0; text-align: center;
}
.h-wall { font-size: var(--t-d-lg); }
.wall-sub { margin-top: .7rem; color: var(--ink-soft); font-family: var(--font-marker); font-size: var(--t-lg); }
.plan {
  max-width: 380px; margin: 2.2rem auto 0; padding: 1.8rem 1.6rem;
  background: var(--sheet); text-align: center;
}
.plan-price { font-family: var(--font-marker); font-size: 2rem; line-height: 1.1; }
.placeholder {
  background: var(--hl-pink); padding: .05em .4em;
  border: 2px dashed var(--ink); border-radius: var(--sketch-chip);
}
.plan-per { display: block; margin-top: .6rem; font-size: var(--t-md); line-height: 1.3; color: var(--ink-soft); font-family: var(--font-sans); }
.plan-blank { margin: 1.5rem 0; font-family: var(--font-marker); font-size: var(--t-body); }
.plan-note { margin-top: 1rem; font-size: var(--t-xs); line-height: 1.5; color: var(--ink-soft); }

/* ===================== how it works ===================================== */
.how {
  max-width: var(--wrap); margin-inline: auto;
  padding: clamp(3.5rem, 8vw, 6rem) var(--pad) clamp(2rem, 4vw, 3rem);
}
.h-how { font-size: var(--t-d-md); margin-bottom: clamp(1.8rem, 4vw, 2.6rem); }
.panels { display: grid; gap: clamp(1.6rem, 3vw, 2.4rem); counter-reset: strip; }
/* The top edge is the alignment line, so nothing reads as broken; heights
   follow their own content, so the row still breathes. Variation earned by
   the content, never an arbitrary offset — that was the version that looked
   like a mistake, and forcing equal heights was the version that looked like
   a stock card grid. */
@media (min-width: 820px) { .panels { grid-template-columns: 1fr 1.18fr 1fr; align-items: start; } }

.strip {
  background: var(--sheet); padding: 1.5rem 1.4rem 1.7rem;
  counter-increment: strip; position: relative;
}
.strip:nth-child(1) { transform: rotate(-.8deg); }
.strip:nth-child(2) { transform: rotate(.6deg); }
.strip:nth-child(3) { transform: rotate(-.5deg); }
.strip::before {
  content: counter(strip); position: absolute; top: -16px; left: -14px;
  width: 40px; height: 40px; display: grid; place-items: center;
  font-family: var(--font-marker); font-size: var(--t-lg); font-weight: 700;
  background: var(--hl-yellow); color: var(--ink);
  border: 2.5px solid var(--ink); border-radius: 50% 48% 52% 50% / 50% 52% 48% 50%;
}
.strip-art { width: 62px; height: 74px; color: var(--ink); filter: url(#rough); }
.strip h3 { font-family: var(--font-marker); font-size: var(--t-xl); margin: .5rem 0 .45rem; letter-spacing: -.01em; }
.strip p { font-size: var(--t-base); color: var(--ink-soft); }

/* ===================== footer =========================================== */
.foot {
  max-width: var(--wrap); margin-inline: auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--pad) 3rem;
  border-top: 2.5px solid var(--rule); margin-top: clamp(2rem, 5vw, 3rem);
  display: flex; justify-content: space-between; align-items: end; gap: 1.4rem; flex-wrap: wrap;
}
.foot-word { font-family: var(--font-marker); font-size: var(--t-2xl); letter-spacing: -.02em; }
.foot-note { font-size: var(--t-sm); color: var(--ink-soft); max-width: 40ch; }

/* ===================== the one authored moment ========================== */
/* The marker draws: the band wipes in, the call settles, the notes follow. */
.report[data-run="1"] .verdict { animation: wipe .5s var(--ease) both; }
.report[data-run="1"] .verdict-call { animation: settle .55s .14s var(--ease) both; }
.report[data-run="1"] .verdict-num { animation: settle .5s .3s var(--ease) both; }
.report[data-run="1"] .note { animation: settle .45s var(--ease) both; animation-delay: var(--d, 0s); }

@keyframes wipe   { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes settle { from { opacity: 0; transform: translateY(9px) rotate(-.6deg); } to { opacity: 1; transform: none; } }

/* `use` content lives in a shadow tree, so the animation rides the <svg> itself. */
.mascot.is-busy { animation: nudge 1.05s ease-in-out infinite; transform-origin: 50% 88%; }
@keyframes nudge { 0%, 100% { transform: rotate(-2.4deg); } 50% { transform: rotate(2.8deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
