/* A Product page: the buy card, the Product's piece on the world's table, and its sections. */
.prod main { padding-top: 96px; }
@media (max-width: 760px) { .prod main { padding-top: 78px; } }

/* The top of the page is the family's kitchen table, edge to edge, under the header: the same wood as the home page's world. */
body.prod { overflow-x: clip; }
/* (body's clip passes to the window, which can still be scrolled sideways by a script or a focused control; main's
   own clip keeps June's arm, drawn out past the table's side, from ever making the page wider.) */
.prod main { overflow-x: clip; }
.p-top { position: relative; isolation: isolate; max-width: 1340px; margin: 0 auto; padding: 8px var(--gap) 40px; display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(330px, 1fr); gap: 36px 44px; align-items: start; }
.p-top::before { content: ""; position: absolute; z-index: -1; top: -96px; bottom: 0; left: calc(50% - 50vw); width: 100vw; background: #c98a4a url(../img/b/table-bg-1200.webp) center top / cover no-repeat; box-shadow: inset 0 -10px 18px -10px rgba(70,40,10,.35); }
.p-buy.card { transform: rotate(-.6deg); box-shadow: 10px 16px 24px rgba(70,40,10,.32); }
.p-show { grid-column: 1; grid-row: 1; min-width: 0; }
.p-buy { grid-column: 2; grid-row: 1; position: sticky; top: 92px; z-index: 3; }
.p-buy h1 { margin: 2px 0 12px; }
.p-name { display: block; font-size: clamp(34px, 3.4vw, 48px); line-height: 1.1; }
.p-sub { display: block; font-size: 19px; line-height: 26px; margin-top: 8px; text-decoration: none; display: block; }
.p-buy .lede { font-size: 18px; line-height: 28px; }
.btn-wide { width: 100%; margin-top: 8px; }
.buy-row { display: grid; gap: 10px; margin: 12px 0 4px; }
.buy-row .btn { width: 100%; }
.sale { margin-top: 4px; }
.soon { font-size: 16px; line-height: 24px; margin: 6px 0 4px; background: var(--manila); border-radius: 4px; padding: 10px 12px; }
.p-buy .fine a, .end-card .fine a { white-space: nowrap; }
@media (max-width: 960px) {
  .p-top { grid-template-columns: minmax(0, 1fr); }
  .p-show, .p-buy { grid-column: 1; grid-row: auto; position: static; }
}
@media (max-width: 760px) {
  .p-top { padding: 6px 12px 24px; gap: 22px; }
  .p-top::before { top: -78px; }
  .p-buy.card { transform: none; }
  .p-buy { padding: 18px 16px 8px; }
  .p-buy .kicker { margin-bottom: 0; }
  .p-buy h1 { margin-bottom: 4px; }
  .p-name { font-size: 32px; }
  .p-sub { font-size: 17px; line-height: 23px; margin-top: 4px; }
  .p-buy .lede { display: none; }
  .p-buy .offer { margin: 8px 0; }
  .p-buy .offer p { font-size: 15px; line-height: 21px; }
  .p-buy .sticker { width: 56px; height: 56px; font-size: 20px; }
  .soon { font-size: 15px; line-height: 21px; padding: 8px 10px; }
  .buy-row { grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
  .buy-row .btn { font-size: 15px; padding: 8px 8px; min-height: 46px; }
  .p-buy .fine { font-size: 13px; line-height: 19px; margin-top: 6px; }
}

/* The piece: with scripts off or the world held still, the parent page and the other eight in a captioned row. */
.p-piece { position: relative; container-type: inline-size; }
.pz-view { display: none; }
.pz-still { margin: 0; background: var(--manila); border-radius: 6px; padding: 18px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; align-items: end; }
.pz-still img { display: block; width: 100%; height: auto; box-shadow: 0 0 0 1.5px rgba(51,54,59,.15), 8px 10px 0 rgba(51,54,59,.08); background: #fff; }
.pz-still figcaption { font-size: 17px; line-height: 26px; }
.pz-row { list-style: none; margin: 14px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.pz-row img { display: block; width: 100%; height: auto; background: #fff; box-shadow: 0 0 0 1.5px rgba(51,54,59,.15); }
/* Each page's caption is a paper label lying under it, so it reads plainly on the wood. */
.pz-row p { font-size: 14px; line-height: 20px; margin: 6px 0 0; background: var(--paper, #fff); color: var(--graphite); padding: 6px 8px; border-radius: 3px; box-shadow: 0 0 0 1px rgba(51,54,59,.15), 2px 3px 6px rgba(70,40,10,.22); }
@container (max-width: 520px) { .pz-still { grid-template-columns: 1fr; } .pz-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container (max-width: 300px) { .pz-still { padding: 12px; } .pz-row { grid-template-columns: minmax(0, 1fr); gap: 18px; } .pz-row li { display: grid; grid-template-columns: 38% minmax(0, 1fr); gap: 12px; align-items: start; } .pz-row p { margin: 0; } }
.pz-ctl, .pz-cap { display: none; }

/* The finished page pictures stay in place until the table's picture has fully arrived and is decoded (pz-ready, set by
   the page's own script beside the poster, or by the piece once its live table is whole): the page never shows bare wood. */
/* (pz-ready only gates them, in :where, so every rule keeps the weight it had before it and the layouts' own rules for
   these parts still win.) */
html.living:where(.pz-ready) .pz-still, html.living:where(.pz-ready) .pz-row { display: none; }
html.living:where(.pz-ready) .pz-view { display: block; }
html.living .pz-view { position: relative; aspect-ratio: 1600 / 1300; overflow: hidden; overflow: clip; perspective: 2400px; touch-action: manipulation; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; }
@container (max-width: 639px) { html.living .pz-view { aspect-ratio: 800 / 1220; } }
/* The table has no edge of its own: where the camera leans in, pages fade into the same wood around it. */
html.living:not(.poster) .pz-view { -webkit-mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent), linear-gradient(transparent, #000 3%, #000 97%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent, #000 3%, #000 97%, transparent), linear-gradient(transparent, #000 3%, #000 97%, transparent); mask-composite: intersect; }
html.poster .pz-view { position: fixed; inset: 0; z-index: 999; aspect-ratio: auto; background: #c98a4a; }
html.poster .top, html.poster .bar, html.poster .btn-calm, html.poster .top, html.poster .bar, html.poster .btn-calm, html.poster .w1-next { display: none !important; }
/* The page keeps its shape under the poster (the wood is laid to it); only the view shows. */
html.poster .p-buy, html.poster .pz-ctl, html.poster .p-piece > :not(.pz-view), html.poster main > :not(.p-top), html.poster .p-show > :not(.p-piece), html.poster footer { visibility: hidden !important; opacity: 0 !important; }
.pz-poster img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Until the table wakes, its picture lies on the wood, its edge feathered into the grain. */
html.living:not(.poster) .pz-poster { display: block; height: 100%; -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent), linear-gradient(transparent, #000 5%, #000 95%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent), linear-gradient(transparent, #000 5%, #000 95%, transparent); mask-composite: intersect; transition: opacity .35s ease; }
.pz-live .pz-poster { opacity: 0; pointer-events: none; }
/* Carried in from the home page: the script lies on top of the stack, where the home page's hands left it. */
.pz-carry { display: none; }
html.carried .pz-carry { display: block; position: absolute; z-index: 2; left: 7.5%; top: 9.14%; width: 38.75%; height: auto; transform: rotate(-1.5deg); background: #fff; box-shadow: 0 0 0 1px rgba(51,54,59,.1), 14px 22px 34px rgba(80,45,10,.28); }
@container (max-width: 639px) { html.carried .pz-carry { left: 11.25%; top: -.28%; width: 77.5%; transform: rotate(-1deg); } }
/* The page under it is the finished poster; the carried script lies on top only once it is a whole picture (the home
   page has it already), so the arrival never shows an empty white sheet. */
html.carried .pz-carry:not(.in) { visibility: hidden; }
/* The table wakes under the picture, with the same script on top: the carried script stays over the picture while it
   fades, and only then gives way to the live one lying beneath it, so the week's first page never shows through. */
.pz-live .pz-carry { opacity: 0; pointer-events: none; transition: opacity .25s ease .32s; }
html.living .p-show .pz-cap { background: var(--paper); border: 1.5px solid var(--graphite); border-radius: 4px; padding: 10px 14px; box-shadow: 6px 10px 16px rgba(70,40,10,.25); }
.pz-view .pg { cursor: pointer; }
.pz-mark { position: absolute; background: rgba(246,195,51,.55); mix-blend-mode: multiply; border-radius: 10px 6px 12px 5px; opacity: 0; pointer-events: none; }
html.living:where(.pz-ready) .pz-ctl { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.pz-ctl .btn { box-shadow: 0 2px 0 var(--graphite); }
.pz-ctl .btn[aria-pressed="true"] { background: var(--yellow); }
/* A tap on the paused table marks the Play button for a moment: that is what starts it again. */
.pz-ctl .btn-calm.nudge { box-shadow: 0 0 0 4px var(--paper), 0 0 0 6.5px var(--graphite); }
/* Paused, a slip under the controls says why the table isn't answering, with its own Play right there. */
.pz-paused { display: none; }
html.living:where(.pz-ready).paused .pz-paused { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; padding: 7px 7px 7px 14px; background: #fff; border: 1.5px solid var(--graphite); border-radius: 4px; scroll-margin: calc(var(--top-h, 64px) + 12px) 0 100px; }
.pz-paused p { margin: 0; font-size: 15px; line-height: 21px; }
.pz-paused .btn-play { flex: none; background: var(--yellow); min-height: 42px; }
.pz-paused .btn-play::before { content: ""; border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent currentColor; }
.pz-paused .btn-play.nudge { box-shadow: 0 0 0 4px var(--paper), 0 0 0 6.5px var(--graphite); }
.btn-calm { scroll-margin: calc(var(--top-h, 64px) + 12px) 0 100px; }
html.living:where(.pz-ready) .pz-cap { display: block; margin: 10px 0 0; min-height: 56px; font-size: 17px; line-height: 26px; }
/* On a desk or a turned tablet the table, its controls and the caption fit one screen together too: a short screen
   gets a smaller table, at the same shape, so pressing a control never has to move them out of reach. */
@media (min-width: 761px) {
  html.living:not(.poster) .pz-view { width: auto; max-width: 100%; margin: 0 auto; height: min(calc(100cqw * 1300 / 1600), calc(100svh - var(--top-h, 64px) - 200px)); }
  /* The controls and the caption are one card lying over the table's near edge: June's arm reaches in from under it,
     her sleeve running on beneath the card, never ending on the open wood. */
  html.living .p-show .pz-ctl { position: relative; z-index: 3; margin-top: -40px; padding: 12px 14px 0; background: var(--paper); border: 1.5px solid var(--graphite); border-bottom: 0; border-radius: 4px 4px 0 0; }
  html.living .p-show .pz-paused { position: relative; z-index: 3; margin-top: 0; border-radius: 0; }
  html.living .p-show .pz-cap { position: relative; z-index: 3; margin-top: 0; border-top: 0; border-radius: 0 0 4px 4px; padding-top: 10px; }
}
.pz-cap b { margin-right: 2px; }
/* On a phone the table, its three controls and the caption fit one screen together: the pause sits on the table's corner. */
@media (max-width: 760px) {
  .p-show { position: relative; }
  html.living .pz-ctl { flex-wrap: nowrap; gap: 6px; margin-top: 10px; }
  html.living .pz-ctl .btn { flex: 1 1 auto; padding: 6px 8px; font-size: 14.5px; min-height: 42px; white-space: nowrap; }
  html.living .pz-ctl .btn-calm { position: absolute; z-index: 5; top: 8px; right: 8px; flex: none; width: 44px; height: 44px; padding: 0; border-radius: 50%; }
  .btn-calm .calm-w { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .btn-calm::before { content: ""; width: 12px; height: 14px; border-left: 4px solid currentColor; border-right: 4px solid currentColor; box-sizing: border-box; }
  .btn-calm[aria-pressed="true"]::before { width: 0; height: 0; border-style: solid; border-width: 8px 0 8px 13px; border-color: transparent transparent transparent currentColor; margin-left: 3px; }
  html.living .p-show .pz-cap { font-size: 15px; line-height: 22px; min-height: 85px; padding: 8px 12px; margin-top: 10px; }
  /* As on the desk, the controls and the caption are one card lying over the table's near edge, so June's arm runs on
     under it and never ends in the table's feathered edge. The table sits under the card (its own layer, below the
     controls), the pause button still on its corner. */
  .p-show { isolation: isolate; }
  html.living .p-show .p-piece { position: relative; z-index: -1; }
  html.living .p-show .pz-ctl { margin-top: -26px; padding: 10px 10px 0; background: var(--paper); border: 1.5px solid var(--graphite); border-bottom: 0; border-radius: 4px 4px 0 0; }
  html.living .p-show .pz-paused { margin-top: 0; border-radius: 0; }
  html.living .p-show .pz-cap { margin-top: 0; border-top: 0; border-radius: 0 0 4px 4px; box-shadow: 6px 10px 16px rgba(70,40,10,.25); }
  /* A short phone gets a smaller table, so the table, its controls and the caption all fit between the header and
     the price bar at the bottom of the screen. */
  html.living:not(.poster) .pz-view { width: auto; max-width: 100%; margin: 0 auto; height: min(calc(100cqw * 1220 / 800), calc(100svh - var(--top-h, 64px) - 296px)); }
  /* Whatever the phone's width, no control ever runs past the card: one that can't fit its row goes onto the next. */
  html.living .pz-ctl { flex-wrap: wrap; }
}
/* A narrower phone: the three controls sit a little closer, on a slightly tighter card, so they keep one row. */
@media (max-width: 400px) {
  html.living .p-show .pz-ctl { gap: 4px; padding: 8px 5px 0; }
  html.living .pz-ctl .btn { gap: 4px; padding: 6px; font-size: 14px; }
  html.living .pz-ctl .btn svg { width: 15px; height: 10px; }
}
@media (max-width: 365px) {
  html.living .pz-ctl .btn { font-size: 13.5px; }
}
/* A screen too short for all three together (a phone at a large zoom, a small window): the table keeps the screen's
   height between the menu and the price bar, big enough to handle, and the controls and the caption follow under it.
   A control pressed down there brings the table back into view (the-spelling-year.js). */
@media (max-width: 760px) and (max-height: 640px) {
  html.living:not(.poster) .pz-view { height: min(calc(100cqw * 1220 / 800), calc(100svh - var(--top-h, 64px) - 100px)); }
}
@media (min-width: 761px) and (max-height: 640px) {
  html.living:not(.poster) .pz-view { height: min(calc(100cqw * 1300 / 1600), calc(100svh - var(--top-h, 64px) - 24px)); }
}
html.living .pz-view { scroll-margin: calc(var(--top-h, 64px) + 8px) 0 92px; }

/* Shared with the home page's table: the week a spot lifts off Sam's map. */
.spot-card { position: absolute; left: 0; top: 0; z-index: 6; width: 284px; padding: 12px 12px 8px; background: #fff; border: 1.5px solid var(--graphite); border-radius: 4px; box-shadow: 0 2px 0 rgba(51,54,59,.15); opacity: 0; transform: translateY(14px) rotate(0deg) scale(.96); transition: opacity 160ms ease, transform 160ms ease, box-shadow 160ms ease; pointer-events: none; }
.spot-card.up { opacity: 1; transform: translateY(0) rotate(-3deg) scale(1); box-shadow: 8px 14px 18px rgba(70,40,10,.28); transition: opacity 220ms ease-out, transform 420ms cubic-bezier(.2,1.4,.4,1), box-shadow 420ms ease-out; pointer-events: auto; }
.sc-pic { position: relative; overflow: hidden; border-radius: 2px; }
.sc-pic img { position: absolute; max-width: none; }
.sc-t { margin: 8px 0 0; font-size: 18px; line-height: 24px; }
.sc-n { color: var(--red); margin-right: 6px; }
.sc-c { margin: 0; font-size: 16px; line-height: 22px; }
.sc-nav { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; }
.sc-b { min-height: 40px; padding: 4px 12px; border: 1.5px solid var(--graphite); border-radius: 20px; background: #fff; color: var(--graphite); font: 700 15px/1 var(--font); cursor: pointer; }
.sc-b[data-d="1"] { margin-left: auto; }
/* Where the whole card won't fit the screen's height, the week lies on a wider, shorter card: its picture beside its
   name, the steps to its neighbours under both. */
.spot-card.sc-wide { display: grid; width: 300px; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "p t" "p c" "n n"; column-gap: 10px; align-items: start; padding: 8px 10px 6px; }
.sc-wide .sc-pic { grid-area: p; }
.sc-wide .sc-t { grid-area: t; margin: 0; font-size: 17px; line-height: 22px; }
.sc-wide .sc-c { grid-area: c; font-size: 15px; line-height: 20px; }
.sc-wide .sc-nav { grid-area: n; margin-top: 6px; }
.spot:focus-visible { outline: 10px solid var(--blue); }
html.paused .spot-card, html.paused .spot-card.up { transition: none; }

/* Sections */
.p-sec { padding: 56px var(--gap); scroll-margin-top: 40px; }
.p-sec:nth-of-type(odd) { background: var(--manila); }
.p-in { max-width: 1180px; margin: 0 auto; }
.p-in.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px 56px; align-items: start; }
.p-sec h2 { margin-bottom: 16px; }
.sec-lede { max-width: 720px; }
/* Week 1 and the free series are one path: the download, then right beside it (below it on a phone) the form that
   brings the next free thing, and the day the year opens. */
.w1-next { margin: 0; }
.w1-next .kicker { margin: 0 0 6px; }
.p-in.one { max-width: 640px; }
.item { background: #fff; border: 1.5px solid var(--graphite); border-radius: 6px; margin-top: 14px; box-shadow: 4px 4px 0 var(--manila); }
.item summary { cursor: pointer; list-style: none; padding: 16px 52px 16px 20px; position: relative; display: block; }
.item summary::-webkit-details-marker { display: none; }
.item summary::after { content: ""; position: absolute; right: 20px; top: 24px; width: 12px; height: 12px; border-right: 2.5px solid var(--graphite); border-bottom: 2.5px solid var(--graphite); transform: rotate(45deg); transition: transform 160ms; }
.item[open] summary::after { transform: rotate(-135deg); top: 30px; }
.item summary h3 { display: block; margin-bottom: 4px; }
.item summary span { display: block; font-size: 16px; line-height: 24px; }
.item > :not(summary) { margin-left: 20px; margin-right: 20px; }
.item > :last-child { margin-bottom: 18px; }
.pages { padding-left: 1.4em; font-size: 17px; line-height: 27px; }
.pages li { margin-bottom: 6px; padding-left: 4px; }
.pages li::marker { color: var(--red); font-weight: 700; }
.weeks { font-size: 17px; line-height: 27px; }
.looks { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; }
.looks figure { margin: 0; }
.looks img { display: block; width: 100%; height: auto; background: #fff; box-shadow: 0 0 0 1.5px rgba(51,54,59,.18), 6px 8px 0 rgba(51,54,59,.08); }
.looks figcaption { font-size: 15px; line-height: 22px; margin-top: 10px; }
.plain { padding-left: 1.2em; }
.plain li { margin-bottom: 10px; }
.plain li::marker { color: var(--red); }
.pad-top { padding-top: 56px; }
@media (max-width: 760px) {
  .p-sec { padding: 40px 14px; }
  .p-in.two { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .looks { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
}
/* A phone on its side: the table fills the screen's height beside its controls and caption, so all of it shows at
   once; it keeps the desk's table (the same pages laid out wide). product.js and the piece ask the same query. */
@media (pointer: coarse) and (max-height: 31.24em) and (min-aspect-ratio: 4/3) {
  .prod main { padding-top: 60px; }
  .p-top::before { top: -60px; }
  .p-top { padding: 6px 12px 24px; gap: 18px; }
  html.living .p-show { --tv: calc(100svh - var(--top-h, 48px) - 22px); display: grid; grid-template-columns: calc(var(--tv) * 1600 / 1300) minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: 12px; align-items: start; scroll-margin-top: calc(var(--top-h, 48px) + 10px); }
  html.living .p-piece { grid-column: 1; grid-row: 1 / 4; }
  html.living:not(.poster) .pz-view { aspect-ratio: 1600 / 1300; width: 100%; height: auto; margin: 0; }
  html.carried .pz-carry { left: 7.5%; top: 9.14%; width: 38.75%; transform: rotate(-1.5deg); }
  html.living .p-show .pz-ctl { grid-column: 2; margin: 0; padding: 10px; flex-wrap: wrap; gap: 6px; background: var(--paper); border: 1.5px solid var(--graphite); border-bottom: 0; border-radius: 4px 4px 0 0; }
  html.living .pz-ctl .btn { flex: 1 1 auto; min-height: 42px; padding: 6px 10px; font-size: 14.5px; white-space: nowrap; }
  html.living .pz-ctl .btn-calm { position: static; }
  /* The card beside the table runs the table's whole height, so June's forearm, coming in from beyond the table's
     right side, always passes under it, whichever line she is on: each part keeps its own row (the pause note's stays
     empty while it is hidden), and the caption fills the last one down to the table's foot. */
  html.living .p-show .pz-ctl { grid-row: 1; align-self: stretch; }
  html.living .p-show .pz-paused { grid-column: 2; grid-row: 2; align-self: stretch; margin: 0; }
  html.living .p-show .pz-cap { grid-column: 2; grid-row: 3; align-self: stretch; }
}
@media (pointer: coarse) and (max-height: 31.24em) and (min-aspect-ratio: 4/3) and (max-width: 760px) {
  html.living .pz-ctl .btn-calm { flex: 0 0 44px; width: 44px; height: 44px; }
  html.living .p-show .pz-paused { grid-column: 2; margin: 0; border-radius: 0; }
  html.living .p-show .pz-cap { grid-column: 2; margin: 0; min-height: 0; border-top: 0; border-radius: 0 0 4px 4px; padding: 8px 12px; font-size: 15px; line-height: 21px; }
}
@media (max-width: 340px) {
  .looks { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .looks img { max-width: 240px; }
  .looks figcaption, .pz-still figcaption { font-size: 16px; line-height: 24px; }
  .pad-top { padding-top: 0; }
  .item summary { padding: 14px 44px 14px 16px; }
  .item > :not(summary) { margin-left: 14px; margin-right: 14px; }
}
