/* === KUEH OF THE DAY === */
/* Background is .matte-metal-surface (styles/atoms.css, applied in
   index.html) instead of the flat --color-surface-tint every other
   section uses — a deliberate departure for this section specifically,
   not a system-wide swap. position: relative is for the two
   .metal-rivet-row-* rows (src/atoms/rivets.js, appended in
   kueh-of-day.js's init()) — decorative riveted-seam edges along the
   panel, positioned absolute against this section rather than affecting
   its layout height. overflow-x: hidden clips those rows cleanly at the
   section's own edge on narrow viewports (see .metal-rivet-row's own
   comment, styles/atoms.css, for why they're allowed to run past it)
   instead of adding page-level horizontal scroll. */
.kueh-of-day-section {
  position: relative;
  overflow-x: hidden;
  padding: 32px 32px 80px;
}

/* Pinned to the section's own left/right edges (32px inset) — this is
   what lets .metal-rivet-row's own justify-content: space-between (styles/
   atoms.css) spread the dots across the section's *real* width at
   whatever size it actually renders, with no vw-based guessing that
   could under/overshoot. That only works while the container has enough
   room; past the point where it doesn't (see the media query below), the
   row switches to a centered, fixed-width layout instead so it can
   overflow both edges symmetrically rather than however space-between
   degrades once there's no free space left to distribute. */
.metal-rivet-row-top,
.metal-rivet-row-bottom {
  position: absolute;
  left: 32px;
  right: 32px;
}

.metal-rivet-row-top {
  top: 14px;
}

.metal-rivet-row-bottom {
  bottom: 14px;
}

/* Below the exact width where the row's own minimum content (5 dots at
   7px + 4 gaps at .metal-rivet-row's 85px floor = 375px, styles/
   atoms.css) plus this container's own 64px inset (32px each side, above)
   no longer fits, justify-content: space-between has nothing left to
   distribute and collapses to flex-start — packing everything against
   the left edge and overflowing one-sided to the right, not the
   symmetric bleed this is going for. Past that point (375 + 64 = 439px),
   switch the container itself to a fixed-width, centered box instead —
   left: 50% + translateX(-50%) centers it regardless of how much wider
   than the viewport it ends up, so the overflow reads evenly on both
   sides. The 438px breakpoint isn't an arbitrary design choice; it's
   solved directly from the row's own numbers above, so if those ever
   change, this needs to move with them. */
@media (max-width: 438px) {
  .metal-rivet-row-top,
  .metal-rivet-row-bottom {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
}

/* Two independent floating "windows" (src/atoms/retro-shape.js) side by
   side, directly on the section's own background — no shared card frame.
   align-items: start keeps each column sized to its own content instead
   of CSS Grid's default row-stretch, which used to make .kod-media match
   .kod-content's height (including growing when the recipe's "see more"
   expanded it) — the media window now always stays its own natural size.
   The middle `auto` track is .kod-seam-wrap (buildSeam, kueh-of-day.js) —
   an explicit column rather than leaving it to fall into an implicit one,
   so its width is just its own content (a thin metal line + a rivet
   column) instead of splitting the gap evenly with the other two tracks.
   The two 24px gaps this creates read as roughly the same total
   media-to-content spacing the old single 40px gap did, just with the
   seam now sitting in the middle of it instead of bare space. */
.kod-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.2fr);
  align-items: start;
  gap: 24px;
}

/* align-self: stretch (overriding .kod-layout's own align-items: start,
   which every other grid item still uses) is what makes this column's
   height follow the grid row's own height — set by whichever of
   .kod-media-column/.kod-content-column renders taller — rather than
   collapsing to its own near-zero content height. That real height is
   what .kod-seam-line's own negative top/bottom offsets below measure
   from to reach the section's actual edges; without it (a near-zero-
   height box) `bottom` would resolve against a bottom edge sitting right
   on top of `top`, not the section's real bottom. width: 24px just gives
   .kod-seam-line/-rivets (both absolutely positioned within it) a
   horizontal anchor at the grid's actual gap position — this element's
   own width otherwise plays no visual role. */
.kod-seam-wrap {
  position: relative;
  align-self: stretch;
  width: 24px;
}

/* The seam line pair itself (.metal-seam/-line, src/atoms/metal-seam.js) —
   centered in .kod-seam-wrap horizontally, but bled vertically past this
   row entirely: top/bottom aren't 0, they're negative by exactly
   .kueh-of-day-section's own top/bottom padding (32px/80px, above), so
   the lines' actual rendered edges land flush with the *section's*
   top/bottom edges rather than stopping at this row's. height: auto
   overrides .metal-seam's own height: 100% — with both top and bottom
   set, an explicit height would win the box model's over-constrained
   resolution instead of letting top+bottom imply it, which is what
   actually produces the full-bleed span. width: 2px is just enough for
   the pair's own 1px + 1px lines, flush against each other (.metal-seam's
   gap: 0) — sized here (not left to shrink-to-fit) since this element
   also needs a known width for left: 50%/translateX(-50%) to center
   correctly. Crossing behind the top/bottom rivet rows (metal-rivet-row-
   top/-bottom, near the very edges) is deliberate, not a collision to
   avoid — a real riveted seam continues underneath a cross-seam, it
   doesn't stop short of it. */
.kod-seam-line {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: -32px;
  bottom: -80px;
  height: auto;
  width: 2px;
}

/* Deliberately not bled the way .kod-seam-line is — these stay within
   this row's own bounds (top/bottom insets past 0), which already sits
   comfortably clear of the top/bottom rivet rows near the section's
   actual edges (32px/80px of section padding, above, versus those rows'
   own 14px inset — see .metal-rivet-row-top/-bottom). Left of the line
   (toward .kod-media-column), offset past the line pair's own 2px width
   plus a gap rather than centered on it, so line + rivets read as one
   riveted seam assembly instead of the dots overlapping the line.
   height: auto overrides .metal-rivet-row-vertical's own height: 100%
   for the same reason .kod-seam-line overrides .metal-seam's — with
   top, bottom, AND an explicit height all present, height wins the box
   model's over-constrained resolution and bottom gets ignored, which
   would blow this past the 12px bottom inset instead of respecting it. */
.kod-seam-rivets {
  position: absolute;
  right: 50%;
  margin-right: 8px;
  top: 12px;
  bottom: 12px;
  height: auto;
}

.kod-media-column {
  display: flex;
  flex-direction: column;
}

.kod-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  /* Top offset isn't the same 16px as the left inset — it's this row's
     own height (32px, just the icon badge) split against
     .tab-group-rim's taller box (~47.5px: its own rim padding + .tab-
     group's padding + .tab's own padding/line-height) so the two boxes'
     vertical *centers* line up despite starting from the same grid-row
     top (.kod-layout's align-items: start) — half the height
     difference, not a matched top margin. */
  margin: 8px 0 14px 16px;
}

/* Unlike every other .section-label (index.html), this one sits directly
   on .matte-metal-surface, not the --color-surface-tint
   --color-text-on-surface is calibrated against — that surface is a
   near-light-gray now (see .matte-metal-surface, styles/atoms.css), so
   dark text reads reliably across it; --metal-shadow (styles/tokens.css)
   is the same dark charcoal .rim-matte-inner uses at the dark end of its
   own gradient, reused here rather than reaching for
   --color-text-on-surface (calibrated for a different, warmer surface).
   A faint light drop-shadow reads as a slight etched-into-the-metal
   recess rather than serving legibility (dark-on-light-gray already has
   plenty of contrast on its own). The .kod-media-column-scoped selector
   (not just .kod-tag) is deliberate, not decorative — .section-label's
   own color rule lives in index.html's inline <style>, which loads
   *after* this stylesheet, so an equal-specificity .kod-tag rule here
   would actually lose that cascade order; the extra ancestor class is
   what wins regardless of load order. */
.kod-media-column .kod-tag {
  color: var(--metal-shadow);
  filter: drop-shadow(0 1px 1px rgba(255, 255, 255, 0.5));
}

/* Circular badge around the tag's kueh icon (32px, metal rim + light
   face) — see buildMediaTag, kueh-of-day.js. Sizing the outer
   .rim-matte-inner element directly (width/height here, not on the face)
   means .rim-matte-inner-glint's own padding (styles/atoms.css) insets
   the face from the rim naturally, the same nesting every other
   .rim-matte-inner consumer relies on. */
.kod-tag-icon-badge {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
}

.kod-tag-icon-face {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* --color-accent — the same fill the kueh photo's own window uses
     (buildMediaWindow, kueh-of-day.js), so the icon badge reads as a
     smaller echo of that window's background rather than picking its
     own separate light palette token. */
  background: var(--color-accent);
}

/* No compensating transform here anymore — this used to nudge the wrap up
   1.5px to paper over the "dome"/"cup" templates' own drawn content
   sitting a few px low of the 64x64 viewBox's true vertical center
   (src/atoms/kueh-icon.js), which read as visibly bottom-weighted once
   cropped tightly into a small circle. Fixed at the source instead (both
   templates' own coordinates now center correctly), so this nudge would
   just over-correct an already-centered icon. The other templates' own
   residual offset (a couple px at most) is small enough to stay invisible
   at any of this icon's usage sizes. */

/* The kueh photo's own window: clipped to a retro-rectangle superellipse
   (clip-path set from JS — src/atoms/retro-shape.js hands back a
   per-instance clipUrl, so it can't be a static rule here) with the
   window's own accent-colored fill + inner shadow painted by its
   .retro-shape-fill child. Wrapped in a .rim-matte-inner /
   .rim-matte-inner-glint metal bezel (src/atoms/matte-rim.js) — the
   drop-shadow that lifts the whole assembly off the page now lives on
   that outer rim (below), not here, since the rim is the true outer edge
   now. No longer stretched to match .kod-content-window's height (see
   .kod-layout) — sized by its own heading + image + padding. */
.kod-media {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 32px;
  min-height: 220px;
}

/* drop-shadow (not box-shadow) is what lifts the retro-rectangle-shaped
   windows off the page: box-shadow would draw a shadow around the
   element's full rectangular border-box regardless of the clip-path,
   while drop-shadow is computed from the actual clipped, rendered
   pixels, so it hugs the silhouette — same reasoning .tab-group-rim
   (molecules.css) uses for its own drop-shadow. Scoped to these two
   columns rather than baked into the shared .rim-matte-inner class
   (styles/atoms.css), since not every future .rim-matte-inner consumer
   necessarily wants to read as a floating card.

   Direct-child combinator (>), not a plain descendant selector — each
   column's own window rim is a direct child (buildMediaColumn/
   buildContentColumn, kueh-of-day.js), but .kod-tag's own icon badge
   (buildMediaTag) is *also* a .rim-matte-inner, nested a couple levels
   deeper inside .kod-tag. A plain descendant selector caught that badge
   too, stacking this filter on top of its own ancestor .kod-tag's
   separate drop-shadow (below) — two nested filter contexts on a small
   circular element, which is exactly the shape WebKit mobile Safari
   renders incorrectly (a square drop-shadow bounding box bleeding
   through the circular clip, instead of hugging the circle). */
.kod-media-column > .rim-matte-inner,
.kod-content-column > .rim-matte-inner {
  filter: drop-shadow(0 4px 20px rgba(0, 0, 0, 0.09)) drop-shadow(0 1px 4px rgba(0, 0, 0, 0.06));
}

/* .retro-shape-fill (first child of both .kod-media and .kod-content-window
   — the filled <path> painting each window's superellipse + inner shadow,
   createRetroShape, src/atoms/retro-shape.js) moved to styles/atoms.css —
   it's a general createRetroShape({fill}) consumer's requirement, not
   KOTD-specific, and a second consumer (src/organisms/check-in.js) needing
   it defined here (where it wouldn't be loaded) is what surfaced that. */

.kod-media img {
  max-width: 100%;
  max-height: 320px;
  height: auto;
  object-fit: contain;
}

.kod-name {
  align-self: flex-start;
  margin-bottom: 10px;
}

.kod-content-column {
  display: flex;
  flex-direction: column;
}

/* Floats directly on the section background now (no card behind it) —
   already carries its own chrome rim + white pill fill
   (src/molecules/tab-group.js), so no changes needed there, just spacing
   before the content window below. */
.kod-content-column .tab-group-rim {
  margin-bottom: 22px;
}

/* The tab panels' own window — same retro-rectangle treatment as .kod-media
   (see the comment there for the .rim-matte-inner wrapper and where its
   drop-shadow now lives), just a white fill (the day's palette doesn't
   touch this one) instead of the accent color. Height changes (switching
   Overview/Recipe tabs, or the recipe collapse expanding/collapsing) are
   driven explicitly to a pixel value by buildContentColumn
   (kueh-of-day.js) rather than left at height: auto, specifically so this
   transition has something numeric to animate between — auto can't
   transition. overflow: hidden clips content that doesn't fit the
   *current* (mid-transition, still animating) height yet, so a growing
   panel reveals smoothly from the top rather than instantly poking out
   past the rim before the box catches up to it. */
.kod-content-window {
  position: relative;
  overflow: hidden;
  padding: 32px 36px;
  transition: height 0.3s ease;
}

.kod-panel {
  display: flex;
  flex-direction: column;
}

.kod-panel[hidden] {
  display: none;
}

.kod-origin-sentence {
  font-size: 1rem;
  line-height: 1.7;
  color: var(--color-text-on-surface);
  margin-bottom: 18px;
}

.kod-flavor-pills {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.kod-flavor-pill {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--color-highlight-soft);
  color: var(--color-text-on-surface);
  border-radius: var(--radius-pill);
  padding: 4px 12px;
}

.kod-recipe-heading {
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--color-text-on-surface);
  margin: 16px 0 8px;
}

.kod-recipe-heading:first-child {
  margin-top: 0;
}

.kod-ingredient-list,
.kod-method-list {
  color: var(--color-text-on-surface);
  font-size: 0.9rem;
  line-height: 1.7;
  padding-left: 1.25em;
}

.kod-recipe-empty {
  font-size: 0.9375rem;
  color: var(--color-text-on-surface-muted);
}

/* max-height's expanded target is set inline by JS (buildContentColumn,
   kueh-of-day.js) as collapse.scrollHeight — a real measured pixel value,
   not max-height: none, which can't transition smoothly (there's no
   interpolatable path from a fixed px value to the "none" keyword).
   overflow: hidden here is what makes that collapse/expand actually clip
   instead of just growing the panel underneath it.

   padding-left/right: this element's own left edge used to sit exactly
   flush with .kod-ingredient-list/.kod-method-list's own left edge (zero
   buffer) — an outside list marker (the default; keeping it, rather than
   list-style-position: inside, is what keeps the numbers and the text
   both in their own clean, consistently-aligned column, wrapped lines
   included) hangs into its padding-left gutter as its own box, and
   mobile Safari's outside-marker layout runs that box close enough to
   the edge that it could poke past a zero-buffer clip boundary, slicing
   off the left stroke of each number. A few px of real breathing room
   between this clip edge and the list's own box is what actually fixes
   that, rather than changing how the list marks itself up. */
.kod-recipe-collapse {
  position: relative;
  max-height: 180px;
  overflow: hidden;
  padding: 0 8px;
  transition: max-height 0.3s ease;
}

.kod-recipe-collapse:not(.expanded)::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 48px;
  background: linear-gradient(to bottom, transparent, var(--color-surface));
  pointer-events: none;
}

/* Everything about the toggle's own look (white fill, the reflective
   liquid-chrome rim, retro-rectangle shape, hover/focus states) comes from
   .btn/.btn-small/.btn-primary/.btn-rim now (styles/atoms.css,
   src/atoms/button.js) — this file only owns what's specific to this
   one instance: where it sits (moved out from inside .kod-content-window
   to below the whole rimmed window, see buildContentColumn, kueh-of-
   day.js), the chevron's rotate-on-expand, and the collapsed state below.
   Visibility is toggled by the tab group's onChange in JS via the
   .kod-see-more-rim-collapsed class, not the `hidden` attribute
   (.btn-rim[hidden]'s display: none, styles/atoms.css, can't transition —
   see buildContentColumn's own comment for why that used to make the
   section's height jump instead of animate alongside the content window). */
.kod-see-more-rim {
  align-self: flex-end;
  margin-top: 16px;
  /* Without this, flex-end lines the button's right edge up with the
     window's own outer rim edge — but that rim (1.5px .rim-matte-inner +
     0.75px .rim-matte-inner-glint padding, styles/atoms.css) plus
     .kod-content-window's own 36px right padding (above) sit outside the
     actual text content, so the button read as hanging further right
     than the text it sits below. 38.25px = 1.5 + 0.75 + 36, pulling the
     button's right edge in to match the text's own right edge instead. */
  margin-right: 38.25px;
  /* 40px is a small buffer over the button's actual rendered height
     (~34.5px) — max-height (not height) is what lets this collapse to a
     fixed 0 without knowing the button's exact height up front the way
     .kod-recipe-collapse's own max-height needs a real measured
     scrollHeight (that content varies per-recipe; this button's doesn't).
     overflow: hidden is what makes max-height actually clip/reveal it
     instead of just changing the box's stated size while content still
     pokes out. */
  max-height: 40px;
  opacity: 1;
  overflow: hidden;
  transition: max-height 0.3s ease, opacity 0.2s ease, margin-top 0.3s ease;
}

.kod-see-more-rim.kod-see-more-rim-collapsed {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  pointer-events: none;
}

.kod-see-more-chevron {
  transition: transform 0.2s ease;
}

.kod-see-more[aria-expanded="true"] .kod-see-more-chevron {
  transform: rotate(180deg);
}

@media (max-width: 640px) {
  .kueh-of-day-section {
    padding: 60px 20px;
  }
  .kod-layout {
    grid-template-columns: 1fr;
  }
  .kod-content-window {
    padding: 24px 20px 28px;
  }
  /* The seam only makes sense as a between-columns divider; stacked to a
     single column, it'd have no real height to stretch to (nothing else
     shares its row) and would render as a near-invisible sliver rather
     than a full-height line. */
  .kod-seam-wrap {
    display: none;
  }
}
