/* The shell is a flex column so the panel is a flex item: that is what gives the
   ratio below an automatic content minimum, and a block box has none. */
/* No clip of its own: the card leaves through the edge of the screen like every other travelling
   region, and the viewport is what hides it (`body` carries `overflow-x: clip`). A clip here bounded
   the exit at the shell box, which sits on the gutter, so the card died on the page frame instead. */
/* The card hangs below the Hello heading (Jan, 2026-09-12), so it takes `--conference-top`, which
   `motion.js` sets from the heading's resting place plus its measured height. `--heading-top` is the
   fallback for the frames before that measurement exists and for the no-script page, where the card
   simply sits where the heading would be rather than nowhere. */
.cf-shell { position: fixed; top: var(--conference-top, var(--heading-top)); left: var(--gutter); width: 40vw; min-width: 480px; z-index: 10; display: flex; flex-direction: column; visibility: hidden; transition: visibility 0s var(--exit); }
/* Two to one, so the panel is a landscape card rather than a column of blocks.
   The ratio sets the height wherever the content fits inside it, and yields to
   the content where it does not: at the 480 px width floor a fixed 240 px would
   cut the Attend button off, and a card slightly taller beats a card with its own
   control clipped. Narrow panels trade padding and gap for that room below. */
/* The card arrives from beyond the left edge of the screen and goes back out the same way (Jan,
   2026-09-07). One resting transform drives both directions — entering is `is-shown` adding it,
   leaving is the class coming off — so it never leaves through an edge it did not arrive through.
   The distance is the site's own off-stage step, `calc(-100% - var(--gutter))`, the same one the
   service cards use in `styles.css`: the shell stands on the gutter, so its own width alone stops
   the card on the page frame rather than clearing the screen. This card is not a special case. */
.cf-panel { position: relative; display: flex; flex-direction: column; gap: 16px; aspect-ratio: 2 / 1; padding: 32px; background: var(--paper); border-radius: var(--radius); overflow: clip; opacity: 0; transform: translateX(calc(-100% - var(--gutter))); transition: opacity var(--exit), transform var(--exit) var(--ease-exit); }
.cf-shell.is-shown { visibility: visible; transition-delay: 0s; }
.cf-shell.is-shown .cf-panel { opacity: 1; transform: none; transition-duration: 640ms; transition-timing-function: var(--ease); }
/* Contour ground: a terrain height field drawn in `conference.js`, faded out of
   the lower left so the countdown and the button stand on plain paper. It sits
   behind the content on a negative layer rather than by lifting every sibling —
   a positioned sibling would become the containing block for the interaction
   preview's stretched card link and trap it inside one row. The fade is on the
   wrapper, not on what it holds: the SVG is the still map, and where WebGL is
   available a canvas over it carries the living one (Jan, 2026-09-09), so the
   two swap beneath one mask and the swap moves nothing. */
.cf-field { position: absolute; inset: 0; z-index: -1; border-radius: inherit; overflow: clip; -webkit-mask-image: linear-gradient(118deg, transparent 26%, #000 72%); mask-image: linear-gradient(118deg, transparent 26%, #000 72%); }
.cf-topo { display: block; width: 100%; height: 100%; }
.cf-topo path { fill: none; stroke: #e3ded3; stroke-width: 1; vector-effect: non-scaling-stroke; }
.cf-topo path.idx { stroke: #d8d1c2; stroke-width: 1.4; }
.cf-live { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.cf-field.is-live .cf-topo { display: none; }

.cf-close { --fill-color: var(--surface-hover); position: absolute; right: 8px; top: 8px; width: 28px; height: 28px; padding: 1px 0 0; border: 0; background: transparent; color: var(--muted); font: 22px/1 var(--sans); border-radius: 5px; transition: background var(--feedback), color var(--feedback); }
.cf-close:is(:hover, :focus-visible) { color: var(--muted); }

/* The occasion is one two-line caption — the conference, then the date it runs on
   — so the session name is the only heading and nothing above it competes. */
.cf-lede > span { display: block; }
.cf-talk { font-size: clamp(26px, 2.2vw, 36px); line-height: 1.2; letter-spacing: -.01em; }
/* City and country share one mono caption role. */
.cf-city, .cf-country { font: 500 11px/1.5 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink); }

/* The heading row stands a fixed step below the caption (Jan, 2026-09-07) and owns the panel's spare
   height: it grows, its own content stays at its top, and the closing row below it is carried to the
   bottom padding by that growth. An auto margin on the row derives the same position from leftover
   space instead, and leftover space is recomputed on layout passes the row's placement was not. */
.cf-head { display: flex; flex: 1 1 auto; align-items: flex-start; justify-content: space-between; gap: 24px; margin-top: 1rem; }
/* The pin rides the heading's line and names the place, so no other line repeats
   it, and it hangs an inset in from the content edge rather than on it. */
.cf-place { display: grid; justify-items: center; gap: 3px; margin-right: 32px; }
.cf-pin { display: block; width: 19px; height: 25px; fill: var(--ink); margin-top: .6rem; }
.cf-city { margin-top: 8px; }

/* The closing row: the countdown and Attend share one line, standing on the bottom padding because
   the heading row above them takes the panel's spare height. Every block above it is fixed, so a
   font that swaps in late lands on the heading and can no longer move these two. */
.cf-bottom { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.cf-clock { display: flex; justify-content: flex-start; gap: 36px; }
.cf-unit { display: grid; justify-items: center; gap: 4px; }
.cf-value { font: 600 var(--figure-size)/1 var(--number); font-variant-numeric: lining-nums tabular-nums; letter-spacing: -.02em; color: var(--ink); }
.cf-cap { font: 10px/1.4 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

/* Solid pill: the ground runs behind this corner, and an outline read as see-through.
   The pill is #444 rather than ink (Jan, 2026-09-07): the hover fill every .btn
   carries is #222, and #222 arriving over #161513 is a change no eye can see, so
   the button read as dead. Written as a literal rather than as --body, which
   happens to be the same grey: that token is the body text colour and a button
   ground has no business moving when it does. */
.cf-meta { display: flex; justify-content: flex-end; }
.cf-link { background: #444; border-color: #444; color: #fff; }

/* Reading flow gives the panel the whole content width, where two to one would be
   a billboard. It takes its height from its content again, so there is no free
   height for the heading row's auto margin to claim. */
.flow .cf-shell { position: relative; top: auto; left: auto; width: 100%; min-width: 0; margin: 0 0 40px; }
.flow .cf-panel { aspect-ratio: auto; }
/* Below a 1400 px viewport the panel sits on its width floor while the ratio keeps
   taking its height down, so it spends less on padding and gap to stay landscape. */
@media (max-width: 1400px) {
  .cf-panel { gap: 12px; padding: 24px; }
  /* On the width floor the closing row buys its fit from the countdown's own
     spacing, rather than dropping Attend onto a second line. */
  .cf-bottom { gap: 16px; }
  .cf-clock { gap: 18px; }
}
/* Reading flow has no room for a pin beside the heading. Both rows dissolve, the
   pin goes, and the place becomes a plain line under the date. The countdown
   keeps its full size here — it is the reason the panel exists. */
@media (max-width: 700px) {
  .cf-panel { aspect-ratio: auto; }
  .cf-head, .cf-bottom { display: contents; }
  .cf-pin { display: none; }
  .cf-place { display: flex; flex-wrap: wrap; gap: 0 6px; margin: 0; }
  .cf-city { margin-top: 0; }
  .cf-city::after { content: ' ·'; }
  .cf-lede { order: 1; }
  .cf-place { order: 2; }
  .cf-talk { order: 3; }
  .cf-clock { order: 4; }
  .cf-meta { order: 5; }
  .cf-field { -webkit-mask-image: linear-gradient(196deg, transparent 42%, #000 88%); mask-image: linear-gradient(196deg, transparent 42%, #000 88%); }
}
@media (max-width: 560px) {
  .cf-panel { padding: 24px 16px; }
}
