/* ==========================================================================
   PLOP! — the table, and the objects that lie on it.

   One surface runs the whole document. Chapters are regions of that surface,
   never boxes on it: there is no card, no panel and no rounded rectangle
   wrapping a section anywhere in this stylesheet. What gives the page its
   structure is the objects themselves and the space between them.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Objects are meant to hang off the edge of the table — a print running past
     the right margin, a disc half out of frame. `clip` has to be on the ROOT,
     not only on body: body's overflow propagates to the viewport in principle,
     but a hanging object still leaves the document horizontally scrollable in
     practice, and a landing you can shove sideways on a phone is a bug. `clip`
     rather than `hidden` because `hidden` would make the root a scroll
     container and break position: sticky further down the page. */
  overflow-x: clip;
  /* the table colour is scroll-linked at the very end of the page; everything
     else reads it from here so the darkening happens in exactly one place */
  --table-now: var(--table);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--table-now);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--t-body);
  line-height: 1.55;
  overflow-x: clip;              /* objects may hang past the edge, never scroll */
  -webkit-font-smoothing: antialiased;
  transition: background-color 900ms linear;
}

/* the grain sits over the table and under everything else */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: var(--grain);
  opacity: .5;
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: 1;
}
body > * { position: relative; z-index: 2; }

img { max-width: 100%; }

h1, h2, h3, h4 { margin: 0; font-weight: 400; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
/* every photograph on this page is a <figure>, and the UA stylesheet gives
   <figure> a 40px side margin — which quietly stops a full-bleed photograph
   reaching either edge and pushes every print 40px off its grid column */
figure, blockquote { margin: 0; }
fieldset { min-width: 0; }

/* --- type ------------------------------------------------------------- */

.display {
  font-family: var(--display);
  letter-spacing: var(--track-display);
  line-height: .88;
  text-transform: uppercase;
  text-wrap: balance;
}
.d-mega { font-size: var(--t-mega); }
.d-huge { font-size: var(--t-huge); }
.d-big  { font-size: var(--t-big); }
.d-mid  { font-size: var(--t-mid); }

.lead { font-size: var(--t-lead); line-height: 1.35; max-width: 30ch; }
.copy { max-width: 42ch; }

/* the label voice: small, spaced, printed on a paper tag */
.label {
  font-family: var(--body);
  font-weight: 600;
  font-size: var(--t-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

/* the annotation voice. Tiny, hand-written, never load-bearing: every note set
   in this face repeats or decorates something already said in real type. */
.hand {
  font-family: var(--hand);
  font-size: clamp(1.05rem, 2.2vw, 1.5rem);
  line-height: 1.05;
  color: var(--ink-soft);
}

.ink-cobalt { color: var(--cobalt); }
.ink-tomato { color: var(--tomato); }
.ink-grass  { color: var(--grass); }
.ink-turq   { color: var(--turquoise); }

/* --- the table's regions ------------------------------------------------ */

.leaf {
  position: relative;
  padding-block: var(--leaf);
}
.hold {
  width: var(--measure);
  margin-inline: auto;
  position: relative;
}

/* --- paper objects ------------------------------------------------------ */

/* A printed photograph: white border, short shadow, a little off-square. */
.print {
  position: relative;
  display: block;
  background: #fff;
  padding: .55rem .55rem 2.6rem;
  box-shadow: var(--lift-photo);
  --tilt: 0deg;
  transform: rotate(var(--tilt));
}
.print > picture, .print > img { border-radius: 1px; }
.print__cap {
  position: absolute;
  left: .9rem; right: .9rem; bottom: .7rem;
  font-family: var(--hand);
  font-size: 1.05rem;
  line-height: 1.1;
  color: var(--ink-soft);
}
/* a print with no written caption keeps a narrower white margin */
.print--bare { padding: .5rem; }

/* A torn paper note. The tear is a clip-path, not an image. */
.note {
  position: relative;
  background: var(--paper);
  padding: 1rem 1.15rem;
  box-shadow: var(--lift-scrap);
  --tilt: 0deg;
  transform: rotate(var(--tilt));
  clip-path: polygon(0 2%, 6% 0, 24% 3%, 47% 0, 71% 3%, 91% 0, 100% 3%,
                     99% 26%, 100% 52%, 98% 77%, 100% 98%, 78% 100%,
                     52% 97%, 27% 100%, 8% 97%, 0 100%, 2% 74%, 0 49%, 2% 24%);
}
.note--cobalt { background: var(--cobalt); color: #fff; }
.note--butter { background: var(--butter); }
.note--turq   { background: var(--turquoise); }
.note--pink   { background: var(--pink); }

/* A sticker: flat colour, a thin white rim, printed hard. */
.sticker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .5rem .95rem;
  border-radius: 999px;
  background: var(--butter);
  border: 3px solid #fff;
  box-shadow: var(--lift-scrap);
  font-family: var(--body);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  --tilt: 0deg;
  transform: rotate(var(--tilt));
}

/* A strip of tape. Semi-transparent, slightly warm, torn at both ends. */
.tape {
  position: absolute;
  width: 8.5rem;
  height: 2.1rem;
  background: rgba(245, 200, 66, .48);
  box-shadow: 0 1px 2px rgba(60, 40, 20, .12);
  clip-path: polygon(3% 8%, 97% 0, 100% 92%, 0 100%);
  pointer-events: none;
  z-index: 3;
}
.tape--blue { background: rgba(49, 191, 195, .45); }
.tape--pink { background: rgba(240, 141, 168, .45); }

/* A numbered stamp. */
.stamp {
  display: inline-grid;
  place-items: center;
  min-width: 3.5rem;
  padding: .35rem .6rem;
  border: 2px dashed rgba(23, 23, 23, .5);
  border-radius: 3px;
  font-family: var(--display);
  font-size: 1rem;
  letter-spacing: .06em;
  color: var(--ink);
  --tilt: 0deg;
  transform: rotate(var(--tilt));
}

/* --- controls ------------------------------------------------------------ */

/* The ticket. Every primary action on this site is one: a punched paper stub
   with two bites out of its sides. */
.ticket {
  --ticket-bg: var(--tomato);
  --ticket-ink: #fff;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .85rem 1.5rem;
  border: 0;
  background: var(--ticket-bg);
  color: var(--ticket-ink);
  font-family: var(--display);
  font-size: clamp(.95rem, 1.6vw, 1.15rem);
  letter-spacing: -.01em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--lift-card);
  --tilt: 0deg;
  transform: rotate(var(--tilt));
  transition: transform var(--t-fast) var(--snap), box-shadow var(--t-fast);
  /* the two punched bites */
  -webkit-mask:
    radial-gradient(circle at left center, transparent 8px, #000 8.5px),
    radial-gradient(circle at right center, transparent 8px, #000 8.5px);
  -webkit-mask-composite: source-in;
  mask:
    radial-gradient(circle at left center, transparent 8px, #000 8.5px),
    radial-gradient(circle at right center, transparent 8px, #000 8.5px);
  mask-composite: intersect;
}
.ticket:hover { transform: rotate(var(--tilt)) translateY(-2px); box-shadow: var(--lift-held); }
.ticket:active { transform: rotate(var(--tilt)) translateY(1px); box-shadow: var(--lift-card); }
.ticket::after { content: '→'; font-family: var(--body); font-weight: 700; }
.ticket--plain::after { content: none; }
.ticket--cobalt { --ticket-bg: var(--cobalt); }
.ticket--grass  { --ticket-bg: var(--grass); }
.ticket--butter { --ticket-bg: var(--butter); --ticket-ink: var(--ink); }

/* The secondary action: a paper tab, not a ticket. */
.tab {
  display: inline-block;
  padding: .6rem 1.1rem .65rem;
  background: var(--paper);
  border: var(--edge);
  border-bottom-width: 3px;
  color: var(--ink);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--lift-scrap);
  --tilt: 0deg;
  transform: rotate(var(--tilt));
  transition: transform var(--t-fast) var(--snap);
}
.tab:hover { transform: rotate(var(--tilt)) translateY(-2px); }

/* --- focus -------------------------------------------------------------- */

:focus-visible {
  outline: var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}
/* on coloured paper the cobalt ring disappears; switch to ink */
.note--cobalt :focus-visible,
[data-head-tone="dark"] :focus-visible { outline-color: var(--butter); }

.skip {
  position: absolute;
  left: 1rem;
  top: -6rem;
  z-index: 100;
  padding: .8rem 1.2rem;
  background: var(--ink);
  color: var(--paper);
  font-weight: 700;
  text-decoration: none;
  transition: top var(--t-fast);
}
.skip:focus { top: 1rem; }

.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- pointer feedback ---------------------------------------------------- */
/* No branded cursor here. The pointer says what a thing does in the ordinary
   way, and core/cursor.js in "context" mode only holds the grabbing state. */
[data-cursor="grab"] { cursor: grab; }
[data-cursor="draw"] { cursor: crosshair; }
html.is-grabbing, html.is-grabbing * { cursor: grabbing !important; }

/* --- no script ----------------------------------------------------------- */
/* index.html ships prerendered, so a reader without JavaScript gets the whole
   page as a plain document. What they lose is the play: the drag, the pile and
   the drawing sheet, all of which announce themselves rather than sitting there
   inert. Anything scripted is hidden until `js` says a script exists. */
.needs-js { display: none; }
html.js .needs-js { display: revert; }
html.js .no-js-only { display: none; }

.noscript {
  max-width: 44rem;
  margin: 6rem auto 2rem;
  padding: 1.6rem;
  background: var(--paper);
  box-shadow: var(--lift-card);
  rotate: -.6deg;
  display: flex;
  flex-direction: column;
  gap: .8rem;
}

.demo-note {
  font-size: var(--t-small);
  color: var(--ink-soft);
  max-width: 46ch;
}
