/* The Link Commons — chapel engineering on Ember's dark ground:
   brass and candlelight for the human side, one thread of green
   where the machines simply say "here". Mobile-first: Steven lives
   on an iPhone, so one column, large targets, nothing hover-born. */
.link-page .link-kicker { color: #c9a227; letter-spacing: .18em; text-transform: uppercase; font-size: .78rem; text-align: center; }
.link-page .link-hero h1 { text-align: center; margin: 8px 0 10px; }
.link-page .btn { min-height: 48px; padding: 12px 18px; font-size: 1rem; }
.link-recall { position: sticky; top: 8px; z-index: 30; background: #5a1414; border: 2px solid #e07a7a; color: #ffd9d9; border-radius: 10px; padding: 16px; margin-bottom: 14px; text-align: center; font-size: 1.05rem; box-shadow: 0 6px 24px rgba(0,0,0,.5); }
.link-toggle { display: flex; gap: 12px; align-items: flex-start; margin: 14px 0; padding: 10px 6px; cursor: pointer; line-height: 1.55; }
.link-toggle input { margin-top: 3px; width: 24px; height: 24px; accent-color: #c9a227; flex: none; }
.link-row { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line, #2a2118); }
.link-row:last-child { border-bottom: none; }
.link-who { min-width: 160px; }
.link-rank { color: #c9a227; font-size: .9em; }
.link-dev { flex: 1; min-width: 170px; }
.link-badges { display: inline-flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.link-status { display: inline-flex; align-items: center; gap: 7px; font-size: .92em; }
.link-dot { width: 12px; height: 12px; border-radius: 50%; display: inline-block; flex: none; }
.link-dot.here { background: #57d977; box-shadow: 0 0 8px #57d977; }
.link-dot.watch { background: #e8b13c; box-shadow: 0 0 8px #e8b13c; }
.link-dot.lost { background: #6f6a61; }
.link-board-coords { font-variant-numeric: tabular-nums; }
.link-row-watch { background: linear-gradient(90deg, rgba(232,177,60,.10), transparent 65%); border-left: 3px solid #e8b13c; padding-left: 10px; border-radius: 4px; }
.link-porch { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.15rem; font-style: italic; color: #d8b36a; margin: 2px 0 8px; }
.link-book-row { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line, #2a2118); line-height: 1.5; }
.link-book-row:last-child { border-bottom: none; }
.link-log { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.7; white-space: pre-wrap; word-break: break-word; }
.link-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 10px 0; }
.link-tile { display: flex; align-items: center; justify-content: center; text-align: center; text-decoration: none; min-height: 52px; }
.link-firstline { font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-size: 1.15rem; color: #d8b36a; margin: 4px 0 8px; }
.link-row-new { background: linear-gradient(90deg, rgba(216,179,106,.16), transparent 70%); border-left: 3px solid #d8b36a; padding-left: 10px; border-radius: 4px; }
.link-honor-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line, #2a2118); }
.link-honor-row:last-child { border-bottom: none; }
.link-keeper-table { width: 100%; border-collapse: collapse; }
.link-keeper-table th, .link-keeper-table td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--line, #2a2118); vertical-align: top; }

/* ---- Audiobooks on the porch: the Commons card rows (shared with the bubble sheet) ---- */
.link-books-h { margin: 14px 0 4px; font-size: 1.02rem; }
.link-book-item { display: flex; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line, #2a2118); }
.link-book-item:last-child { border-bottom: none; }
.link-book-cover { width: 52px; height: 52px; object-fit: cover; border-radius: 8px; flex: none; }
.link-book-main { flex: 1; min-width: 0; }
.link-book-title { font-weight: 600; line-height: 1.35; }
.link-book-listen { flex: none; min-height: 44px; display: inline-flex; align-items: center; text-decoration: none; }
.link-books-open { display: flex; justify-content: center; align-items: center; margin-top: 14px; min-height: 52px; text-decoration: none; font-size: 1.05rem; }

/* ---- The Porch Bubble + its Living Glass menu sheet ----
   The sheet wears the house glass (glass.css .glass: --glass-pane,
   specular edge, blur) deepened with the pane-deep gradient so text
   stays readable over the blur. It floats above the auto-hiding
   bottom tab bar (bottom offset clears bar + bubble), opens with
   transform/opacity only, and stills for reduced motion. */
#porchRoot { position: fixed; right: 16px; bottom: calc(112px + env(safe-area-inset-bottom)); z-index: 95; }
/* THE WAY BACK (build 2026.11.05.7 — Steven's order: "a back
   button site wide like a bubble"): the porch bubble's mirror
   twin, riding the lower LEFT at the very perch the porch stack
   keeps on the right — the same 112px floor over the tab bar,
   the same 22px rest on wide screens — so the two stacks stand
   level and never meet. Living glass, ember glow, a gold rim;
   a Velvet member's bubble wears the rim in full gold
   (body.velvet-tier is the router's own Velvet word — a
   cosmetic kindness only). renderBackBubble in app.js hangs it
   on inner rooms and keeps it off the front door. */
.back-bubble { position: fixed; left: 16px; bottom: calc(112px + env(safe-area-inset-bottom)); z-index: 95; width: 58px; height: 58px; border-radius: 50%; border: 1px solid var(--glass-edge-gold, rgba(201,162,39,.42)); background: var(--glass-spec), var(--glass-pane-deep); -webkit-backdrop-filter: blur(18px) saturate(1.6); backdrop-filter: blur(18px) saturate(1.6); color: #ffe9b0; font-family: var(--serif, 'Cormorant Garamond', Georgia, serif); font-size: 1.55rem; line-height: 1; cursor: pointer; box-shadow: var(--glass-shadow, 0 18px 50px rgba(0,0,0,.55)), inset 0 1px 0 rgba(255,244,214,.30), 0 0 18px rgba(232,179,75,.22); display: flex; align-items: center; justify-content: center; padding: 0; transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease; }
.back-bubble-glyph { transform: translateY(-1px); }
.back-bubble:hover { border-color: var(--gold, #c9a227); box-shadow: var(--glass-shadow, 0 18px 50px rgba(0,0,0,.55)), inset 0 1px 0 rgba(255,244,214,.34), 0 0 24px rgba(232,179,75,.38); }
.back-bubble:active { transform: scale(.94); }
body.velvet-tier .back-bubble { border: 1.5px solid var(--gold, #c9a227); box-shadow: var(--glass-shadow, 0 18px 50px rgba(0,0,0,.55)), inset 0 1px 0 rgba(255,244,214,.38), 0 0 26px rgba(232,179,75,.45); }
@media (min-width: 761px) {
  .back-bubble { bottom: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .back-bubble { transition: none; }
  .back-bubble:active { transform: none; }
}
.porch-bubble { position: relative; width: 58px; height: 58px; border-radius: 50%; border: 1px solid rgba(255,236,200,.38); background: linear-gradient(180deg, rgba(148,26,40,.94), rgba(26,10,20,.96)); color: #ffe9b0; font-size: 1.5rem; cursor: pointer; box-shadow: 0 10px 28px rgba(0,0,0,.55), inset 0 1px 1px rgba(255,255,255,.28), 0 0 18px rgba(232,179,75,.22); display: flex; align-items: center; justify-content: center; margin-left: auto; padding: 0; touch-action: none; cursor: grab; }
.porch-bubble:active { cursor: grabbing; }
/* The breathing candle-glow: a halo layer behind the bubble that
   only ever animates opacity and transform — cheap on any phone —
   and stands still for reduced motion. */
.porch-bubble::after { content: ""; position: absolute; inset: -7px; border-radius: 50%; background: radial-gradient(circle, rgba(232,179,75,.38), rgba(232,179,75,.10) 55%, transparent 72%); opacity: .3; transform: scale(.96); animation: porchGlow 3.8s ease-in-out infinite; pointer-events: none; z-index: -1; }
@keyframes porchGlow { 0%, 100% { opacity: .26; transform: scale(.95); } 50% { opacity: .58; transform: scale(1.07); } }
/* ---- Bubble v3: the bubble pops up. On arrival it springs in from
   small with an overshoot while its halo blooms once — transform and
   opacity only — then settles into the ordinary breathing glow. The
   tucked ember dot pops in exactly the same way. ---- */
.porch-bubble.pop-in { animation: porchPop .45s cubic-bezier(.22, 1.45, .36, 1) both; }
@keyframes porchPop { 0% { transform: scale(.4); opacity: 0; } 55% { opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
.porch-bubble.pop-in::after { animation: porchPopBloom .45s ease-out both; }
@keyframes porchPopBloom { 0% { opacity: 0; transform: scale(.5); } 55% { opacity: .85; transform: scale(1.35); } 100% { opacity: .3; transform: scale(1); } }
/* ---- The greeting pill: a small glass word that blooms out of the
   bubble's left side at the bubble's own perch height, speaks once,
   and retracts. It sits clear of the bottom tab bar (it rides the
   root, which the perch clamps) and clear of the drag path. ---- */
.porch-pill { position: absolute; right: calc(100% + 10px); top: 50%; z-index: 2; max-width: min(238px, calc(100vw - 108px)); padding: 10px 14px; border-radius: 999px; border: 1px solid rgba(255,236,200,.22); background: var(--glass-spec), var(--glass-pane-deep); -webkit-backdrop-filter: blur(18px) saturate(1.6); backdrop-filter: blur(18px) saturate(1.6); box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(255,244,214,.32); color: #f3e2b8; font: inherit; font-size: .9rem; line-height: 1.35; text-align: left; cursor: pointer; opacity: 0; transform: translateY(-50%) translateX(8px) scale(.92); transform-origin: right center; transition: opacity .22s ease, transform .3s cubic-bezier(.22, 1.36, .36, 1); }
/* ---- GO LIVE, docked on the bubble (build .23): a lit pill riding
   just above the bubble at its own perch — visible at a glance on
   every signed-in page, one tap, no menu. It rides the root, so the
   drag carries it; it folds away when the bubble tucks and while
   any sheet stands open over the house. ---- */
/* PILLS, MAXED (build 2026.11.04.2, Steven's order: "Both."): the
   Go Live pill is the house's flagship action and is dressed like
   it — a generous 52px tap target, the on-air red deepened, a
   candlelit-gold rim and inner ring, and the same slow breathing
   glow family as the maxed NEW pill (3.8s, the house's candle
   rhythm), stilled for reduced motion by the rule below. Dress
   only: the tap, the flow, and the words are exactly as they were. */
.porch-golive { position: absolute; right: 0; bottom: calc(100% + 12px); z-index: 3; display: inline-flex; align-items: center; padding: 13px 20px; min-height: 52px; border-radius: 999px; border: 1px solid #ffe9b0; background: linear-gradient(180deg, #d42a40, #8a1224); color: #fff3d6; font: inherit; font-weight: 800; font-size: 1rem; letter-spacing: .03em; white-space: nowrap; cursor: pointer; box-shadow: 0 10px 26px rgba(0,0,0,.55), 0 0 18px rgba(255,64,64,.5), inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px rgba(255,217,138,.28); animation: porchGoLivePulse 3.8s ease-in-out infinite; }
@keyframes porchGoLivePulse { 0%, 100% { box-shadow: 0 10px 26px rgba(0,0,0,.55), 0 0 12px rgba(255,64,64,.38), inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px rgba(255,217,138,.28); } 50% { box-shadow: 0 10px 26px rgba(0,0,0,.55), 0 0 32px rgba(255,64,64,.78), inset 0 1px 0 rgba(255,255,255,.4), inset 0 0 0 1px rgba(255,217,138,.28); } }
#porchRoot.is-tucked .porch-golive { display: none; }
#porchRoot:has(.porch-veil.show) .porch-golive { display: none; }
.porch-pill.hidden { display: none; }
.porch-pill.show { opacity: 1; transform: translateY(-50%); }
.porch-pill b { color: #ffe9b0; }
.porch-veil { position: fixed; inset: 0; z-index: 96; background: rgba(4,2,6,.52); opacity: 0; transition: opacity .22s ease; }
.porch-veil.hidden { display: none; }
.porch-veil.show { opacity: 1; }
.porch-sheet { position: absolute; right: 16px; bottom: calc(186px + env(safe-area-inset-bottom)); width: min(362px, calc(100vw - 32px)); max-height: min(68vh, 620px); overflow-y: auto; border-radius: 20px; padding: 18px; background: var(--glass-spec), var(--glass-pane-deep); -webkit-backdrop-filter: blur(22px) saturate(1.7); backdrop-filter: blur(22px) saturate(1.7); box-shadow: var(--glass-shadow), inset 0 1px 0 rgba(255,244,214,.38), inset 0 -18px 34px rgba(0,0,0,.30); opacity: 0; transform: translateY(14px) scale(.98); transition: opacity .24s ease, transform .32s cubic-bezier(.22, 1.36, .36, 1); }
.porch-veil.show .porch-sheet { opacity: 1; transform: none; }
@media (min-width: 761px) {
  #porchRoot { bottom: 22px; }
  .porch-sheet { bottom: 96px; }
}
@media (prefers-reduced-motion: reduce) {
  .porch-veil, .porch-sheet { transition: none; }
  .porch-sheet { transform: none; }
  .porch-bubble::after { animation: none; }
  .porch-veil.show .porch-item { animation: none; }
  .porch-veil.show .porch-sheet::after { animation: none; display: none; }
  .porch-bubble.pop-in { animation: none; }
  .porch-bubble.pop-in::after { animation: none; }
  .porch-living-icon { animation: none; }
  .porch-pill { transition: none; transform: translateY(-50%); }
  .porch-golive { animation: none; }
}
.porch-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 4px; }
.porch-title { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.3rem; color: #e8c87a; }
.porch-x { background: rgba(255,255,255,.05); border: 1px solid var(--glass-edge, rgba(255,236,200,.16)); color: #ffe9b0; border-radius: 10px; width: 40px; height: 40px; cursor: pointer; font-size: 1rem; flex: none; }
.porch-h { margin: 12px 0 2px; font-size: 1rem; }
.porch-h-top { margin-top: 6px; font-size: 1.08rem; }
.porch-velvet-sec { border: 1px solid rgba(232,179,60,.35); border-radius: 14px; padding: 10px 12px; margin-top: 12px; background: linear-gradient(180deg, rgba(122,16,48,.18), rgba(255,255,255,.02)); }
/* Build .24 — THE MATCHING BUILD (Steven's phone, 2026-11-04):
   the .22 rows stood as one flex line with the nowrap door
   pinned right, and at sheet width the words were crushed into
   a ribbon a word wide. The row wraps now: the words carry a
   real basis and read at a natural width, and when a line and
   its door cannot share the row, the door takes its own line
   beneath — right-aligned, the way the sheet's own item arrows
   sit — so no width ever squeezes the text again. */
.porch-velvet-line { display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: center; padding: 5px 0; font-size: .92rem; line-height: 1.4; }
/* Every Door Opens (build 2026.11.04.10): a Velvet line that
   carries a door is itself the tap. */
.porch-velvet-line:has(.porch-velvet-door) { cursor: pointer; }
.porch-velvet-text { flex: 1 1 11rem; min-width: 0; }
.porch-velvet-door { color: #e8c87a; text-decoration: none; white-space: nowrap; font-weight: 600; flex: none; margin-left: auto; }
.porch-open { display: flex; justify-content: center; align-items: center; min-height: 50px; margin-top: 12px; text-decoration: none; }
.porch-menu { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.porch-item { display: flex; gap: 12px; align-items: center; width: 100%; min-height: 58px; padding: 10px 12px; border-radius: 14px; border: 1px solid rgba(255,236,200,.12); background: rgba(255,255,255,.04); color: inherit; text-decoration: none; text-align: left; cursor: pointer; font: inherit; box-shadow: inset 0 1px 0 rgba(255,240,205,.10); }
/* The sheet's first row wears the same light as the docked pill —
   one name, one treatment, everywhere Go Live is offered. */
.porch-item-live { border-color: #ffe9b0; background: linear-gradient(180deg, rgba(212,42,64,.5), rgba(138,18,36,.5)); box-shadow: inset 0 1px 0 rgba(255,255,255,.32), inset 0 0 0 1px rgba(255,217,138,.22), 0 0 18px rgba(255,64,64,.38); }
/* Doors pass (build 2026.11.04.1): every bubble entry wears the door's gold arrow. */
.porch-item::after { content: "→"; color: #e8b34b; margin-left: auto; font-size: 1.15rem; opacity: .85; flex-shrink: 0; padding-left: 8px; }
.porch-item-live .porch-item-name { color: #fff3d6; }
.porch-ico { font-size: 1.45rem; flex: none; }
.porch-item-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.porch-item-name { font-weight: 600; }
.porch-item-line { font-size: .88rem; color: var(--muted, #b8a888); line-height: 1.35; }
.porch-hide { display: block; margin: 14px auto 2px; background: none; border: none; color: var(--muted, #b8a888); font-size: .88rem; cursor: pointer; padding: 8px 10px; text-decoration: underline; }
/* ---- Bubble v2: the tucked ember dot. The bubble never vanishes —
   tucked, it folds to a slim lit dot pinned at the edge, still
   visibly Ember, until a tap lifts it back to the full bubble. ---- */
.porch-bubble.tucked { width: 28px; height: 28px; font-size: 0; border-color: rgba(255,236,200,.5); background: radial-gradient(circle at 50% 36%, #fff3d6 0%, #e8b34b 32%, #e5383b 64%, #7d1420 100%); box-shadow: 0 4px 14px rgba(0,0,0,.5), 0 0 13px rgba(232,179,75,.5); }
.porch-bubble.tucked::after { inset: -4px; }
/* ---- The greeting: name, rank, and the member's true standing ---- */
.porch-who { margin: 2px 0 2px; }
.porch-who-name { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.24rem; font-weight: 600; color: #f3e2b8; }
.porch-who-rank { color: #d8b36a; font-size: 1.02rem; }
.porch-who-velvet { font-size: .9rem; color: var(--muted, #b8a888); margin-top: 1px; }
/* ---- Continue listening: the player card's thin heard-bar ---- */
.porch-progress { height: 5px; border-radius: 99px; background: rgba(255,255,255,.12); overflow: hidden; margin: 5px 0 4px; max-width: 220px; }
.porch-progress i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, #a31621, #e8b34b); }
/* ---- The rows rise in turn as the sheet opens (transform/opacity
   only, staggered by the --i each row carries) ---- */
.porch-veil.show .porch-item { animation: porchRise .38s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(var(--i, 0) * 35ms); }
@keyframes porchRise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
/* ---- A breath of light sweeps the pane as it opens ---- */
.porch-sheet { overflow-x: hidden; }
.porch-sheet::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 55%; background: linear-gradient(100deg, transparent, rgba(255,244,214,.13), transparent); transform: translateX(-150%) skewX(-16deg); pointer-events: none; }
.porch-veil.show .porch-sheet::after { animation: porchSweep .95s ease .06s both; }
@keyframes porchSweep { to { transform: translateX(280%) skewX(-16deg); } }
/* ---- The install sheet: the door onto the home screen ---- */
.porch-install-hero { display: flex; justify-content: center; margin: 8px 0 2px; }
.porch-install-hero img { border-radius: 18px; box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 16px rgba(232,179,75,.25); }
.porch-install-line { font-size: .95rem; line-height: 1.45; color: #e5d9c3; margin: 8px 0; }
/* ---- Bubble v4: the Float candle's little theater — the loop's
   tall frame is shown in a capped window (object-fit keeps the
   bubble orb in view); the PiP floater itself uses the full frame,
   which is the browser's business, not the sheet's. ---- */
.porch-float-video { display: block; width: 100%; height: 300px; object-fit: cover; object-position: center 62%; border-radius: 14px; background: #0a0510; border: 1px solid rgba(255,236,200,.16); box-shadow: 0 10px 26px rgba(0,0,0,.5), 0 0 18px rgba(232,179,75,.16), inset 0 1px 0 rgba(255,244,214,.14); margin: 10px 0 4px; }
/* ---- The living icon (build .9): a home-screen icon cannot move —
   Apple and Google freeze them all — but inside the house the flame
   breathes where it appears: the install sheet's hero and the Float
   sheet's poster. A gentle flicker (a breath of scale and sway, the
   light rising and settling) rides the house's own 3.8s breathing
   halo. Transform, opacity's cousins and filter only — and reduced
   motion stills the flame completely, in the block above. ---- */
.porch-living-icon { transform-origin: 50% 100%; animation: porchIconFlicker 2.8s ease-in-out infinite, porchIconHalo 3.8s ease-in-out infinite; }
@keyframes porchIconFlicker { 0%, 100% { transform: scale(1) skewX(0deg); filter: brightness(1); } 28% { transform: scale(1.018) skewX(.45deg); filter: brightness(1.09); } 54% { transform: scale(.995) skewX(-.35deg); filter: brightness(1.03); } 78% { transform: scale(1.03) skewX(.6deg); filter: brightness(1.12); } }
@keyframes porchIconHalo { 0%, 100% { box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 12px rgba(232,179,75,.20); } 50% { box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 27px rgba(232,179,75,.44); } }
.porch-steps { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.porch-step { display: flex; gap: 10px; align-items: flex-start; background: rgba(255,255,255,.04); border: 1px solid rgba(255,236,200,.12); border-radius: 12px; padding: 10px 12px; font-size: .93rem; line-height: 1.4; }
.porch-step b { color: #e8c87a; }
/* ---- Connect, made obvious (build .8): the teaching card at the
   top of the Commons page, its plain numbered steps, the lit strip
   that replaces it once a device stands linked, and the single
   pulse that points at the form when the card's button is tapped. */
.link-howto-steps { margin: 10px 0 14px; padding-left: 22px; line-height: 1.65; }
.link-howto-steps li { margin: 4px 0; }
.link-connected-strip { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.link-connected-strip #linkConnectedText { flex: 1 1 240px; line-height: 1.5; }
.link-form-pulse { animation: linkFormPulse 1.6s ease-out 1; }
@keyframes linkFormPulse { 0% { box-shadow: 0 0 0 0 rgba(232,179,75,0), 0 0 0 rgba(232,179,75,0); } 25% { box-shadow: 0 0 0 2px rgba(232,179,75,.85), 0 0 26px rgba(232,179,75,.35); } 100% { box-shadow: 0 0 0 0 rgba(232,179,75,0), 0 0 0 rgba(232,179,75,0); } }
@media (prefers-reduced-motion: reduce) { .link-form-pulse { animation: none; } }

/* ---- Bubble v6: quick rail, page-aware lead, dressing room,
 * first-run setup (build 2026.11.02) ---- */
.porch-quick-rail { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.porch-chip {
  display: inline-flex; align-items: center; gap: 7px; padding: 10px 14px; min-height: 44px;
  border-radius: 999px; border: 1px solid var(--line-gold); cursor: pointer;
  background: linear-gradient(180deg, var(--card), var(--card2)); color: var(--txt);
  font-family: var(--serif); font-size: 1rem; letter-spacing: .01em;
  box-shadow: inset 0 1px 0 rgba(232,179,75,.16), 0 4px 14px rgba(0,0,0,.35);
  transition: transform .2s ease, box-shadow .2s ease;
}
.porch-chip:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 rgba(232,179,75,.22), 0 6px 18px rgba(0,0,0,.4), 0 0 12px rgba(232,179,75,.18); }
.porch-chip.soft { background: var(--card2); font-size: .95rem; min-height: 40px; padding: 8px 12px; }
.porch-chip-ico { font-size: 1.05rem; }
.porch-item-fixed { margin-top: 10px; border: 1px solid var(--line-gold); border-radius: var(--r); }

.dr-preview { border: 1px dashed var(--line-gold); border-radius: var(--r); padding: 12px 14px; margin: 10px 0; background: var(--card2); }
.dr-preview-label { font-family: var(--serif); color: var(--gold); margin-bottom: 6px; }
.dr-row { display: flex; align-items: center; gap: 10px; padding: 9px 2px; border-bottom: 1px dashed var(--line); flex-wrap: wrap; }
.dr-row:last-child { border-bottom: none; }
.dr-row.tucked { opacity: .6; }
.dr-ico { font-size: 1.15rem; }
.dr-name { flex: 1 1 150px; font-family: var(--serif); font-size: 1.05rem; color: var(--txt); }
.dr-candle { color: var(--candle); font-size: .85rem; }
.dr-tuckword { color: var(--dim); font-size: .85rem; font-style: italic; }
.dr-btns { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.dr-full { color: var(--candle); font-family: var(--serif); font-size: 1.05rem; }

.setup-warm { font-family: var(--serif); font-size: 1.25rem; color: var(--candle); }
.setup-choices { display: flex; flex-direction: column; gap: 9px; margin: 14px 0; }
.setup-chip {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 14px 16px; min-height: 54px; border-radius: var(--r); cursor: pointer;
  border: 1px solid var(--gold); color: var(--txt);
  background: linear-gradient(180deg, var(--card), var(--card2));
  font-family: var(--serif); font-size: 1.12rem;
  box-shadow: inset 0 1px 0 rgba(232,179,75,.18), 0 0 12px rgba(232,179,75,.14);
}
.setup-chip:active { transform: scale(.99); }
.setup-go { width: 100%; padding: 15px; font-size: 1.12rem; margin-top: 4px; }

@media (prefers-reduced-motion: reduce) {
  .porch-chip, .setup-chip { transition: none; }
  .porch-chip:hover { transform: none; }
}
