/* cardboard.site: the unpacking box (anim.js; review/06-animatie-bouw.md). Only transform, opacity, visibility
   and a clip; no layout per frame. Without JavaScript or with reduced motion everything stands in its end state. */

/* The boxes. The markup holds two states: .cb-live (the end state, drawn per frame by anim.js) and .cb-start (the
   closed box). The inline script in the head picks the closed box before the first paint when an animation is due. */
.cb-box mask * { vector-effect: none; }
.cb-box .cb-start { display: none; }
.cb-intro [data-cb="hero"]:not(.cb-play) .cb-start, .cb-unpack [data-cb="panel"]:not(.cb-play) .cb-start { display: inline; }
.cb-intro [data-cb="hero"]:not(.cb-play) :is(.cb-live, .cb-trail), .cb-unpack [data-cb="panel"]:not(.cb-play) .cb-live { visibility: hidden; }

/* Failsafe: if anim.js never runs (blocked, failed), the end state shows after 2.5 s anyway. Should anim.js still
   arrive after that, it leaves the box open (anim.js checks this before it arms). */
@keyframes cb-show { to { visibility: visible; } }
@keyframes cb-hide { to { visibility: hidden; } }
@keyframes cb-open { to { clip-path: none; } }
.cb-intro:not(.cb-armed) [data-cb="hero"] :is(.cb-live, .cb-trail), .cb-unpack:not(.cb-armed) [data-cb="panel"] .cb-live { animation: cb-show 0s 2.5s forwards; }
.cb-intro:not(.cb-armed) [data-cb="hero"] .cb-start, .cb-unpack:not(.cb-armed) [data-cb="panel"] .cb-start { animation: cb-hide 0s 2.5s forwards; }
.cb-unpack:not(.cb-armed) [data-unbox] { animation: cb-open 0s 2.5s forwards; }

/* The form panel and its box. The box stands on the top edge of the panel, on the right, open like the box in the
   hero (its flaps up). It shrinks with the panel, so its left flap never leaves the screen, also at 200 percent zoom;
   open it is about 94 px high on a laptop and 83 on a phone. The space is kept from the first paint: no shift. */
.panel[data-unbox] { position: relative; margin-top: 98px; }
.cb-pbox { position: absolute; right: clamp(16px, 18%, 130px); bottom: 100%; width: clamp(64px, 28%, 100px); height: auto; overflow: visible; margin-bottom: -1px; pointer-events: none; }
.cb-pbox * { vector-effect: non-scaling-stroke; }
@media (max-width: 600px) { .panel[data-unbox] { margin-top: 86px; } .cb-pbox { width: clamp(64px, 26%, 88px); right: clamp(12px, 14%, 64px); } }
/* Folded before it unfolds: the panel is clipped below its top edge (the box above it stays in view), with two
   creases where it was folded. anim.js unfolds it; the creases fade once it lies flat. */
.cb-unpack [data-unbox] { clip-path: inset(-200px -60px 100% -60px); }
.cb-crease { position: absolute; inset: 0; pointer-events: none; opacity: 0; color: inherit; }
.cb-crease::before, .cb-crease::after { content: ""; position: absolute; left: 22px; right: 22px; border-top: 1.5px dashed currentColor; opacity: .3; }
.cb-crease::before { top: 33.3%; }
.cb-crease::after { top: 66.6%; }
.cb-unpack .cb-crease { opacity: 1; }

/* The hint: the same box, small, in every button to a call or the analysis. It scales with the text of the button.
   On hover and focus both flaps lift (one small overshoot, then still); pressed, a little further. By itself at most
   twice a session (anim.js). */
.box-ico { display: inline-flex; flex: none; line-height: 0; margin: 0 var(--cb-mr, 0px) 0 var(--cb-ml, -.15em); }
.cb-glyph { width: var(--cb-w, 1.6em); height: auto; overflow: visible; }
.cb-glyph * { vector-effect: non-scaling-stroke; }
.cb-glyph .cb-flap { transform-box: view-box; transition: transform .24s cubic-bezier(.34, 1.56, .64, 1); }
.has-box:hover .cb-flap, .has-box:focus-visible .cb-flap, .has-box.cb-peek .cb-flap { transform: var(--lift); }
.has-box:active .cb-flap { transform: var(--lift2); }
/* On kraft the box would melt into the button: its front turns tape-light, the ink line does the rest. */
.btn-kraft .cb-glyph .g1 { fill: #EFDDBC; }
.btn-kraft .cb-glyph .g2 { fill: #DDB78A; }

/* One rule everywhere: per place and language the box is full size where every button there stays on one line with
   it, a size smaller (1.4 em) where only that fits, and away where neither fits, so the buttons of a place look alike.
   Widths in em of the container (any text size), measured on its content box in Chromium and WebKit at pixel ratio 1
   to 3, plus .2 em (anim/test/fit-steps.mjs, fit-css.py; review/06-animatie-bouw.md). Hero and button rows share. */
.hero-act, .ctas { container: cb-row / inline-size; }
.choice { container: cb-choice / inline-size; }
.cta-bar { container: cb-bar / inline-size; }
@container cb-row (max-width: 19.45em) { .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-row (max-width: 19.1em) { .box-ico:lang(nl) { display: none; } }
@container cb-row (max-width: 20.6em) { .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-row (max-width: 20.3em) { .box-ico:lang(en) { display: none; } }
@container cb-choice (max-width: 19.05em) { .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-choice (max-width: 18.75em) { .box-ico:lang(nl) { display: none; } }
@container cb-choice (max-width: 19.9em) { .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-choice (max-width: 19.7em) { .box-ico:lang(en) { display: none; } }
@container cb-bar (max-width: 22.3em) { .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-bar (max-width: 21.6em) { .box-ico:lang(nl) { display: none; } }
@container cb-bar (max-width: 18.6em) { .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
@container cb-bar (max-width: 17.85em) { .box-ico:lang(en) { display: none; } }
/* The header: the box may never cut into the word "Cardboard". Its room changes at the site's breakpoints (380, 600,
   1100: the navigation), so the widths per range. */
.top-in { container: cb-top / inline-size; }
@media (max-width: 380px) {
  @container cb-top (max-width: 18.95em) { .top-act .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 18.6em) { .top-act .box-ico:lang(nl) { display: none; } }
  @container cb-top (max-width: 18.05em) { .top-act .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 17.7em) { .top-act .box-ico:lang(en) { display: none; } }
}
@media (min-width: 380.02px) and (max-width: 600px) {
  @container cb-top (max-width: 21.95em) { .top-act .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 21.7em) { .top-act .box-ico:lang(nl) { display: none; } }
  @container cb-top (max-width: 21.15em) { .top-act .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 20.9em) { .top-act .box-ico:lang(en) { display: none; } }
}
@media (min-width: 600.02px) and (max-width: 1099.98px) {
  @container cb-top (max-width: 23.85em) { .top-act .box-ico:lang(nl) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 23.55em) { .top-act .box-ico:lang(nl) { display: none; } }
  @container cb-top (max-width: 20em) { .top-act .box-ico:lang(en) { --cb-w: 1.4em; --cb-ml: -.2em; --cb-mr: -2px; } }
  @container cb-top (max-width: 19.65em) { .top-act .box-ico:lang(en) { display: none; } }
}
@media (min-width: 1100px) {
  @container cb-top (max-width: 43.65em) { .top-act .box-ico:lang(nl) { display: none; } }
  @container cb-top (max-width: 38.35em) { .top-act .box-ico:lang(en) { display: none; } }
}

/* The click: the small box flies to the box on the form page (cross-document view transition). The opt-in itself is
   inline in the head (Chromium skips a transition when it only finds it in a stylesheet still loading). The page
   itself cuts over at once: a crossfade of a paper page into a navy one goes through grey with both texts on top of
   each other. Only the box, and your idea, fly. */
html[data-from] [data-unbox] .cb-pbox { view-transition-name: cb-box; }
/* At the click the small box closes its flaps at once: it is taken along closed, and lands closed. */
html[data-cb-go] .has-box .cb-flap { transform: none !important; transition: none !important; }
html[data-from] .top { view-transition-name: cb-top; }
::view-transition-old(root) { animation: none; opacity: 0; }
::view-transition-new(root) { animation: none; opacity: 1; mix-blend-mode: normal; }
::view-transition-group(cb-top), ::view-transition-old(cb-top), ::view-transition-new(cb-top) { animation: none; }
::view-transition-old(cb-top) { opacity: 0; }
::view-transition-group(cb-box) { animation-duration: 340ms; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
::view-transition-old(cb-box) { animation: cb-fade-out 120ms linear both; }
::view-transition-new(cb-box) { animation: cb-fade-in 120ms linear both; }
/* Your idea goes into the box: its snapshot starts at half size at its end nearest the box, shrinks on and lands with
   the box at 340 ms, never over the heading of the new page (end and target set in pagereveal). */
::view-transition-old(cb-idea) { animation: cb-idea-in 340ms both; transform-origin: var(--cb-idea-o, 50%) 50%; mix-blend-mode: normal; }
@keyframes cb-fade-out { to { opacity: 0; } }
@keyframes cb-fade-in { from { opacity: 0; } }
@keyframes cb-idea-in {
  from { transform: translate(0px, 0px) scale(.5); opacity: 1; animation-timing-function: cubic-bezier(.2, .8, .2, 1); }
  25% { transform: translate(calc(var(--cb-idea-dx, 0px) * .12), calc(var(--cb-idea-dy, -12px) * .12)) scale(.3); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  85% { opacity: 1; }
  to { transform: translate(var(--cb-idea-dx, 0px), var(--cb-idea-dy, -12px)) scale(.06); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cb-glyph .cb-flap { transition: none; }
  .has-box:hover .cb-flap, .has-box:focus-visible .cb-flap, .has-box.cb-peek .cb-flap, .has-box:active .cb-flap { transform: none; }
}
