/*
story.css. A product's own page (story.js), laid in the product's field on the same twelve columns as everything else.
The product brings three colours: its field, its ink, and --glow, its own light, spent on the firefly's heart; the keys are in the ink. Nothing else is
coloured.
*/
.p-sheet.story { --dim: color-mix(in srgb, var(--ink) 62%, transparent); --hair-s: color-mix(in srgb, var(--ink) 16%, transparent); --mast-h: 60px; scroll-behavior: smooth }
@media (prefers-reduced-motion: reduce) { .p-sheet.story { scroll-behavior: auto } }
.p-sheet.story .s-mast { height: var(--mast-h); margin-bottom: calc(var(--mast-h) * -1); padding-block: 0; align-items: center; background: color-mix(in srgb, var(--field) 70%, transparent); -webkit-backdrop-filter: blur(16px) saturate(1.3); backdrop-filter: blur(16px) saturate(1.3) }
/* over the opening the mast is nothing but its words, so the sky runs to the top edge. It takes its backing only as
   the opening leaves, in the last stretch before the page's words would pass under it */
@supports (animation-timeline: scroll()) {
  .p-sheet.story .s-mast { animation: st-mast linear both; animation-timeline: scroll(nearest); animation-range: calc(100svh - var(--mast-h) * 3) calc(100svh - var(--mast-h)) }
  @keyframes st-mast { from { background: transparent; -webkit-backdrop-filter: blur(0) saturate(1); backdrop-filter: blur(0) saturate(1) } }
}
/* the one key, where Close would be. Over the sky it is only the firefly and its words, one more point of light; once
   the sky has gone it is the key, a square slab in the page's own white, and the firefly's heart stays lit on it. It steps aside while the key at the end is on screen */
.st-add { grid-column: 7 / -1; justify-self: end; display: inline-flex; align-items: center; gap: 10px; height: 40px; padding: 0 18px 0 12px; text-decoration: none; font-weight: 600; font-size: .9375rem; letter-spacing: -.01em; color: var(--ink); transition: background .45s var(--out), color .45s var(--out), font-weight .45s var(--out), box-shadow .2s, opacity .4s var(--out), translate .4s var(--out), transform .25s var(--out) }
.st-add svg { width: 22px; height: 22px; flex: none; color: var(--ink); transition: color .45s var(--out), rotate .8s var(--out) }
.st-add .core { fill: var(--glow); transition: fill .45s var(--out) } .st-add .halo { transition: opacity .45s var(--out) }
.st-add .h0 { stop-color: var(--glow); stop-opacity: .6 } .st-add .h1 { stop-color: var(--glow); stop-opacity: 0 }
.st-add span { border-bottom: 1px solid transparent; transition: border-color .2s }
.st-add:not(.keyed):hover span { border-bottom-color: currentColor }
.st-add:hover svg { rotate: 45deg }
.st-add.keyed { background: var(--ink); color: var(--field); font-weight: 800 }
.st-add.keyed svg { color: var(--field) }
.st-add.keyed:hover { box-shadow: inset 0 0 0 2px var(--field), 0 0 0 2px var(--ink) }
.st-add:active { transform: scale(.97); transition-duration: 0s }
.st-add.away { opacity: 0; translate: 0 -6px; pointer-events: none }
@media (prefers-reduced-motion: reduce) { .st-add, .st-add svg { transition: none } }
.p-sheet.story ::selection { background: var(--glow); color: var(--field) }

/* ── the opening: the plate you pressed, now the page ── */
.st-open { position: relative; height: 100svh; min-height: 560px; display: grid; align-items: end; overflow: clip; isolation: isolate }
.st-open img { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; object-fit: cover }
/* the drawing lies over a still of the thing, star on ring, and gives way to it once the plate has arrived */
.st-open .st-still ~ .st-draw { animation: st-reveal 2.6s 1.3s var(--out) both }
@keyframes st-reveal { to { opacity: 0 } }
.st-open::after { content: ''; position: absolute; inset: 55% 0 0; z-index: -1; background: linear-gradient(transparent, color-mix(in srgb, var(--field) 70%, transparent)) }
.st-open-in { width: 100%; align-items: end; padding-bottom: clamp(20px, 3vw, 44px); row-gap: 6px }
.st-open .s-no { grid-column: 1 / -1; font-size: clamp(.8rem, 1.1vw, 1rem) }
.st-open .s-name { grid-column: 1 / span 8 }
/* what it is sits under the name exactly where the plate had it, so pressing the plate leaves it still. The line is the mood, on the right, set the same so the two read as a pair */
.st-kind { grid-column: 1 / span 8; font: 500 clamp(.74rem, .95vw, .875rem)/1.3 'Atkinson Hyperlegible Next', var(--text); letter-spacing: .2em; text-transform: uppercase; margin-top: .9em }
.st-line { grid-column: 9 / -1; grid-row: 2 / span 2; align-self: end; justify-self: end; text-align: right; font: 500 clamp(.74rem, .95vw, .875rem)/1.3 'Atkinson Hyperlegible Next', var(--text); letter-spacing: .2em; text-transform: uppercase }
@media (prefers-reduced-motion: no-preference) { .st-line { animation: st-in 1.2s .7s var(--out) both } @keyframes st-in { from { opacity: 0; translate: 0 10px } } }

/* ── the admission, said large and slowly ── */
.st-truth { padding-block: clamp(120px, 20vw, 300px) clamp(100px, 16vw, 240px); row-gap: .5em }
.st-truth p { grid-column: 2 / span 9; font-size: clamp(1.65rem, 3.8vw, 3.5rem); line-height: 1.12; letter-spacing: -.028em; font-weight: 500; text-wrap: balance }
.st-truth .st-made, .st-truth .st-then { margin-top: 1.3em }
/* the sky finishes the last sentence, so it follows the words closely and runs edge to edge */
.st-truth .st-live { margin-top: clamp(40px, 6vw, 96px) }

/* ── every part after it: a numbered head, then the thing ── */
.st-mat, .st-end { padding-block: clamp(22px, 2.6vw, 34px) clamp(80px, 11vw, 170px); row-gap: clamp(28px, 3.4vw, 48px); align-items: start }
/* the number sits over its title, both on the section's own left edge, where everything under them starts */
.st-h { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; row-gap: 14px; margin-bottom: clamp(20px, 3vw, 44px) }
.st-no { grid-column: 1 / -1; font-size: .8125rem; color: var(--dim) }
.st-h h2 { grid-column: 1 / -1; font-weight: 500; font-size: clamp(2rem, 4.4vw, 4.2rem); line-height: 1; letter-spacing: -.045em }
.st-intro { grid-column: 3 / span 7; display: grid; gap: .8em; font-size: clamp(1.1rem, 1.5vw, 1.4rem); line-height: 1.42; letter-spacing: -.01em; text-wrap: pretty }
.st-intro p + p { color: var(--dim) }

/* a live frame: the product itself, running in the page */
.st-frame { position: relative; background: #000; overflow: hidden }
.st-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; color-scheme: dark }

.st-live { grid-column: 1 / -1; margin: 0 calc(var(--m) * -1) }
.st-wide { aspect-ratio: 16 / 9; max-height: 86svh; width: 100% }

/* ── what it is made of: the figures, each with what it means ── */
.st-fig { grid-column: span 4; display: grid; gap: 10px; align-content: start }
.st-fig .num { font-size: clamp(2rem, 3.9vw, 3.8rem); line-height: 1.05; letter-spacing: -.04em; white-space: nowrap }
.st-fig .num small { font: 500 .9375rem var(--text); letter-spacing: 0; color: var(--dim); margin-left: .7em }
.st-fig > p:last-child { color: var(--dim); max-width: 36ch; text-wrap: pretty }
/* drawn from the things themselves (a product's own made.draw, such as fireflies-made.js). Each figure stands over
   its material and is counted in as the material arrives under it. What the hand is on is named on a card beside it */
.fm-reads { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid }
.fm-read { grid-column: span 6 }
.fm-fig { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap }
.fm-fig .num { font-size: clamp(2.6rem, 5.4vw, 5.2rem); line-height: 1; letter-spacing: -.045em }
.fm-unit { font-weight: 500 }
.fm-say { margin-top: 14px; max-width: 46ch; color: var(--dim); text-wrap: pretty }
.fm-sky { grid-column: 1 / -1; display: grid; justify-items: center; margin-top: clamp(28px, 4vw, 56px); touch-action: pan-y; outline: none }
.fm-wrap { position: relative }
.fm-wrap canvas, .fm-photo { position: absolute; inset: 0 }
.fm-wrap canvas:first-of-type { mix-blend-mode: screen }
.fm-photo { width: 100%; height: 100%; opacity: 0; transition: opacity 3s ease-in-out } .fm-photo.on { opacity: 1 }
.fm-sky:focus-visible .fm-wrap { box-shadow: 0 0 0 1px var(--hair-s) }
.fm-card { position: absolute; left: 0; top: 0; z-index: 2; display: grid; gap: 3px; width: max-content; max-width: min(34ch, 80vw); padding: 10px 14px 12px; background: color-mix(in srgb, var(--field) 88%, transparent); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); box-shadow: 0 0 0 1px var(--hair-s); pointer-events: none; opacity: 0; transition: opacity .25s var(--out) }
.fm-card[data-on] { opacity: 1 }
.fm-card b { font-weight: 600 } .fm-card span { color: var(--dim); font-size: .875rem } .fm-card small { margin-top: 5px; font-size: .8125rem; line-height: 1.4; color: var(--ink) }
.fm-poems { margin-top: clamp(96px, 13vw, 190px) }
.fm-shelf { grid-column: 1 / -1; position: relative; margin-top: clamp(40px, 5vw, 72px); display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 28px 22px }
/* every full row of the shelf runs edge to edge; the last one keeps to the left */
.fm-shelf::after { content: ''; flex: 1 }
.fm-grp { display: grid; gap: 10px }
.fm-row { display: flex; align-items: flex-end; gap: 3px; height: 78px; border-bottom: 1px solid color-mix(in srgb, var(--ink) 30%, transparent) }
/* --k is how much a spine is under the hand, 0 to 1, eased every frame by fireflies-made.js. It lifts, lights and glows by it */
.fm-sp { --k: 0; width: 3px; height: calc(var(--h) * 14px + 22px); padding: 0; border: 0; border-radius: 1px 1px 0 0; cursor: default; outline: none;
  background: color-mix(in srgb, var(--ink) calc(34% + 66% * var(--k)), transparent); translate: 0 calc(var(--k) * -8px);
  box-shadow: 0 0 calc(var(--k) * 14px) color-mix(in srgb, var(--ink) calc(var(--k) * var(--k) * 45%), transparent);
  transition: translate .6s var(--out), opacity .6s var(--out) }
.fm-shelf[data-ready] .fm-sp { transition: none }
.fm-card.glide { transition: opacity .25s var(--out), translate .32s var(--out) }
.fm-who { display: flex; gap: 6px; font-size: .75rem; color: var(--dim); white-space: nowrap } .fm-who .num { font-size: .5625rem; padding-top: .3em }
@media (prefers-reduced-motion: no-preference) {
  .fm-shelf:not([data-in]) .fm-sp { opacity: 0; translate: 0 12px }
  .fm-shelf[data-in]:not([data-ready]) .fm-sp { transition-delay: calc(var(--i) * 4ms) }
}
.st-credit { grid-column: 1 / span 8; font-size: .8125rem; color: var(--dim); margin-top: clamp(12px, 2vw, 28px); max-width: 90ch }
.st-credit a { color: var(--ink) }

/* ── what is yours, then care, the key and the name ── */
.st-end { padding-top: clamp(80px, 11vw, 170px) }
.st-yours { grid-column: 1 / span 10; font-size: clamp(1.1rem, 1.5vw, 1.35rem); line-height: 1.42; color: var(--dim); text-wrap: pretty }
/* the promise is the statement of the section, said as large as the admission; how it works sits quietly under it */
.st-promise { font-size: clamp(1.65rem, 3.4vw, 3.1rem); line-height: 1.14; letter-spacing: -.028em; font-weight: 500; color: var(--ink); text-wrap: balance; margin-bottom: clamp(18px, 2vw, 28px) }
.st-promise span, .st-care span { display: block } .st-care span + span { margin-top: .18em } .st-yours > p:not(.st-promise) { max-width: 52ch }
.st-care { grid-column: 1 / span 9; margin-top: clamp(40px, 7vw, 110px); font-size: clamp(1.65rem, 3.4vw, 3.1rem); line-height: 1.14; letter-spacing: -.028em; font-weight: 500; text-wrap: balance }
.st-buy { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 14px 24px; margin-top: clamp(16px, 2vw, 28px) }
.st-key { display: inline-flex; align-items: center; height: 60px; padding: 0 30px; background: var(--ink); color: var(--field); font-weight: 800; font-size: 1.0625rem; text-decoration: none; box-shadow: 0 0 48px color-mix(in srgb, var(--ink) 12%, transparent); transition: transform .25s var(--out), box-shadow .3s var(--out) }
.st-key:hover { box-shadow: 0 0 0 3px var(--field), 0 0 0 5px var(--ink), 0 0 64px color-mix(in srgb, var(--ink) 18%, transparent) }
.st-key:active { transform: scale(.97); transition-duration: 0s }
.st-sign { grid-column: 1 / -1; margin-top: clamp(64px, 9vw, 140px) }
.st-sign .whole { height: 24px; width: auto }

/* things arrive as they are reached, tied to the scroll, never to a timer. The admission lights as it is read */
@supports (animation-timeline: view()) { @media (prefers-reduced-motion: no-preference) {
  .st-care span { animation: st-lit linear both; animation-timeline: view(); animation-range: entry 30% cover 45% }
  .st-truth p, .st-promise, .st-care:not(:has(span)) { animation: st-lit linear both; animation-timeline: view(); animation-range: entry 20% cover 42% }
  .st-h, .st-live, .st-fig { animation: st-rise linear both; animation-timeline: view(); animation-range: entry 0% entry 70% }
  @keyframes st-lit { from { opacity: .14 } to { opacity: 1 } }
  @keyframes st-rise { from { opacity: 0; translate: 0 32px } to { opacity: 1; translate: none } }
} }

@media (max-width: 860px) {
  /* on a phone the line goes above the number, so the number, name and kind stay where the plate had them */
  .st-open .s-name, .st-kind, .st-line { grid-column: 1 / -1 } .st-line { grid-row: 1; justify-self: start; text-align: left; margin-bottom: 18px }
  .st-open .s-no { grid-row: 2 } .st-open .s-name { grid-row: 3 } .st-kind { grid-row: 4 }
  .st-truth p { grid-column: 1 / -1 }
  .st-intro, .st-yours, .st-care, .st-buy, .st-sign, .st-credit { grid-column: 1 / -1 }
  .st-wide { aspect-ratio: 4 / 5; max-height: 78svh }
  .st-fig { grid-column: span 6 } .fm-read { grid-column: 1 / -1 } .fm-read + .fm-read { margin-top: 36px }
}
@media (max-width: 520px) { .st-fig { grid-column: 1 / -1 } }
