:root {
  --tby-cream: #F5F0E8;
  --tby-navy: #0A1628;
  --tby-gold: #C9A84C;
  --tby-gold-dark: #A8872E;
  --tby-gold-muted: #7A6020;
  --tby-teal: #1D9E75;
  --font-display: 'Cormorant Garamond', 'Playfair Display', serif;
  --font-body: 'Inter', 'DM Sans', system-ui, sans-serif;
}

/* --- Image treatment: no hard rectangular borders anywhere on the site.
   .img-card = product card images (rounded corners + light shadow)
   .img-bleed = hero/lifestyle photos (edge to edge, no border/radius/shadow)
   .img-gallery = gallery grid tiles (rounded corners only, no shadow) --- */

.img-card {
  display: block;
  width: 100%;
  height: auto;
  border: none;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.img-bleed {
  display: block;
  width: 100%;
  height: auto;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.img-gallery {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: none;
  border-radius: 10px;
  box-shadow: none;
}

* {
  box-sizing: border-box;
}

/* Locked visual calibration (cream sections): linen crosshatch weave
   (navy, 6x6 tile) layered under a scattered gold constellation motif -
   both inline SVG, not raster, per the exact stroke widths/opacities
   Claude Design specified. Replaces the old tby-constellation-cream-bg.png
   raster background sitewide (that PNG is now unused - confirmed round-4:
   this inline SVG pair is the "cream constellation asset" actually
   rendering on every cream section, since none of them set their own
   background-color).
   Round-4 addition: a third layer, a smooth vertical gradient (no grain/
   texture - that was tried and read too heavy in an earlier round) that
   repeats in soft ~1400px bands down the page, giving cream sections a
   little depth instead of reading as one flat fill.
   Round-5 fix: that gradient's first version went 0% bright -> 100%
   slightly-dark, so every ~1400px repeat-y tile boundary jumped straight
   from "slightly dark" back to "bright" with no transition - a hard seam
   wherever that boundary happened to land (it landed inside the Events
   carousel section, which is what read as a banded highlight strip behind
   the section header). Fixed by making the gradient symmetric (0% and
   100% are the same value, dipping in the middle) so repeat-y tiles are
   seamless - the wave just continues, no boundary anywhere on the page.
   Round-5: the constellation used to be a small 260x260 tile with 9 fixed
   stars - even after densifying it in round 2, a tile that small still
   repeats 5-6 times across a normal viewport and reads as an obvious
   pattern rather than an organic field. Replaced with a generated,
   randomized 1600x1600 field (270 irregularly-sized/spaced stars, only a
   handful in small connected clusters, the rest unconnected). At 1600px
   square, it doesn't visibly repeat within any normal viewport in either
   axis.
   Round-7 fix: pure-uniform-random placement doesn't look uniform to the
   eye - by chance it left visible dense patches and thin patches, which
   read as "unbalanced" wherever a section's crop of the tile happened to
   land on one of those patches. Regenerated with a jittered 15x18 grid (one
   star per ~107x89 cell, jittered within the cell) instead of pure random,
   which bounds the max gap/cluster size by construction - no crop of any
   section can land on a genuinely empty or overcrowded zone. The small
   connected clusters are now placed round-robin, one per macro-region of
   the grid, instead of wherever random placement happened to put stars
   close together - see gen-constellation.js (round-7 session) for the
   generator.
   Round-13: every url() reference to these two files carries a `?v=N`
   query param, bumped each time the SVG content changes (see all 4 usages:
   body/here, .how-it-works, .site-footer, .faq-list). Same filename +
   changed content is a classic caching trap - a round-10 fix that verified
   correct in the file still read as "unchanged" live, most likely because
   the browser/CDN kept serving a cached copy of the old bytes under the
   same URL. Bumping the query string forces every layer of caching to
   treat it as a new resource. ALWAYS bump this version number (all 4
   spots, keep them matching each other) whenever gen-constellation.js is
   re-run with different output - the version bump is not optional, it's
   the only thing that makes cache invalidation reliable here. */
body {
  font-family: var(--font-body);
  color: var(--tby-navy);
  background-color: var(--tby-cream);
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0.45) 0%, rgba(10, 22, 40, 0.02) 50%, rgba(255, 255, 255, 0.45) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Cpath d='M0 0L6 6M6 0L0 6' stroke='%230A1628' stroke-width='0.6' opacity='0.015'/%3E%3C/svg%3E"),
    url("/constellation-cream.svg?v=13");
  background-repeat: repeat-y, repeat, repeat;
  background-position: center top, center top, center top;
  background-size: 100% 1400px, 6px 6px, 1600px 1600px;
  margin: 0;
}

h1, h2, h3, .font-display {
  font-family: var(--font-display);
}

.page-content {
  max-width: 1100px;
  margin: 0 auto;
  padding: 2rem 1rem 4rem;
}

a {
  color: inherit;
}

.btn {
  display: inline-block;
  padding: 0.75rem 1.6rem;
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  border-radius: 8px;
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  transition: box-shadow 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.btn-primary {
  background: var(--tby-navy);
  color: var(--tby-cream);
}

.btn-primary:hover {
  background: #16263f;
}

.btn-gold {
  background: var(--tby-gold);
  color: var(--tby-navy);
  box-shadow: 0 6px 24px rgba(201, 168, 76, 0.28);
}

/* Locked calibration (item 4b): teal is exclusively the hover signal for
   every primary gold CTA button sitewide - gold stays the resting state. */
.btn-gold:hover {
  background: var(--tby-teal);
  box-shadow: 0 8px 28px rgba(29, 158, 117, 0.32);
  transform: translateY(-1px);
}

.btn-outline {
  background: transparent;
  border-color: var(--tby-navy);
  color: var(--tby-navy);
}

.btn-outline:hover {
  background: var(--tby-navy);
  color: var(--tby-cream);
}

.btn[disabled], .btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
  transform: none;
}

.gold-italic {
  color: var(--tby-gold);
  font-style: italic;
}

.gold-word {
  color: var(--tby-gold);
  font-style: normal;
}

/* Round-6 star-dot "i": scoped, manual per-instance treatment (per spec -
   NOT a global font/CSS swap) applied only inside the hero headline and
   the section display headlines (How It Works, Theme Explorer, Events
   carousel, See What's Inside). The base character is U+0131 (dotless
   "ı"), which every Latin font renders without a tittle, so a real dot
   never peeks out from under the star at any size/zoom. The actual
   letter "i" is preserved for assistive tech via role="img"
   aria-label="i" on the wrapping span (screen readers announce it as a
   single "i" glyph, the same pattern used for icon-substituted
   characters/emoji). The star reuses the site's existing sparkle-icon
   path (same shape as the search-bar/custom-theme icons elsewhere) for
   brand consistency, sized in em so it scales with each heading's own
   clamp()'d font-size. Vertical offset is tuned to sit where the tittle
   would be - re-check by screenshotting at real rendered size (not
   zoomed) if this is ever reused somewhere with different line-height.
   Round-7 fix: -0.05em was measured against the wrong reference - that
   value sits near the top of the dotless glyph's own line box (close to
   the font's ascent line), which is well above x-height/where a real
   tittle sits, so the star read as floating above the letter rather than
   replacing the dot. Moved down to 0.14em, landing just above x-height
   (the actual tittle position) instead of up near the ascender.
   Round-18 audit: applies to section-level h2 display headlines only (per
   the original round-6 scope), not h3 sub-items/card titles, body copy,
   subheads, buttons, or nav - confirmed every h1/h2 containing a lowercase
   "i" has this treatment; the two that were missing it ("See it in
   action", "Questions, answered") were simply never touched when this
   pattern was first rolled out, not a scope question. h1/h2 with no "i" in
   their text ("Type a theme...", "Made for every moment.") correctly have
   no markup - nothing to check there. */
.i-star {
  position: relative;
  display: inline-block;
}

.i-star-glyph {
  position: absolute;
  width: 0.34em;
  height: 0.34em;
  left: 50%;
  top: 0.14em;
  transform: translateX(-50%);
  color: var(--tby-gold);
}

.subtitle {
  color: rgba(10, 22, 40, 0.6);
  margin-top: -0.5rem;
}

/* --- Site header / nav --- */

.site-header {
  background: var(--tby-cream);
  border-bottom: 1px solid rgba(10, 22, 40, 0.1);
  position: sticky;
  top: 0;
  z-index: 20;
}

.header-inner {
  max-width: 1200px;
  height: 74px;
  margin: 0 auto;
  padding: 0 2rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.site-logo-link {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* Round-17: as the hero/other sections gained richer color treatments
   across recent rounds, the nav (this logo + the link text below) stayed
   at its original values and started reading washed-out by comparison.
   tby-logo.png is a flat raster PNG (not SVG), so individual strokes/dots
   inside it can't be targeted separately - a blanket saturate/contrast
   filter is the only lever available, applied uniformly across the gold
   T-mark and the teal constellation dots alike.
   Round-18: round-17's saturate(1.25) contrast(1.1) wasn't strong enough -
   pushed both substantially further. Also addressing "stroke weight"
   specifically: a filter can't literally thicken geometry baked into a
   raster image, but stacking a small drop-shadow with zero blur-radius
   spread and a tight blur creates a colored halo hugging every opaque
   edge in the PNG (it has a transparent background), which reads as
   bolder/thicker strokes without touching the source pixels - the closest
   approximation available without image-editing tools. */
.site-logo {
  height: 46px;
  width: auto;
  filter: saturate(1.7) contrast(1.35) drop-shadow(0 0 0.6px rgba(201, 168, 76, 0.9));
}

/* margin-left: auto anchors this group to the far right of the header. */
.header-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-left: auto;
}

.header-actions .btn {
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
}

/* .btn-gold's sitewide box-shadow (a soft gold glow, meant to lift CTAs off
   busier backgrounds) reads as an unwanted framed box against the header's
   plain cream background - drop it here specifically rather than changing
   .btn-gold itself, which is used correctly elsewhere. */
.header-actions .btn-gold {
  box-shadow: none;
}

/* Hidden by default (no items) - only fades in once something's in the
   cart, via addToCart()/saveCart() -> updateCartBadge() toggling
   "cart-visible". Kept in normal flow (not display:none) so the fade-in
   doesn't shift the "Start Designing" button when it appears. */
.cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.35s ease;
}

.cart-link.cart-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.cart-icon {
  width: 22px;
  height: 22px;
}

.cart-icon .cart-icon-line {
  stroke: var(--tby-navy);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.15s ease;
}

.cart-link:hover .cart-icon-line {
  stroke: var(--tby-gold);
}

.cart-count {
  position: absolute;
  top: -6px;
  right: -8px;
  background: var(--tby-gold);
  color: var(--tby-navy);
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1;
  border-radius: 999px;
  padding: 0.2rem 0.4rem;
  min-width: 0.65rem;
  text-align: center;
}

/* --- Site footer --- */

/* Revised per fix-batch spec (2026-07-17): footer now carries the same
   navy constellation texture as .how-it-works, at the same tighter density
   (300x300 tile, 9 stars) for consistency between the two navy panels -
   supersedes the earlier "flat navy, no texture" calibration.
   Round-2: dropped this rule's old margin-top:3rem. .constellation-seam
   (the standalone gold star/dot line between FAQ and footer) only reads
   as a seam if it sits flush against the color change it's straddling -
   the 3rem gap pushed the navy background 48px below the seam, leaving
   it stranded in a wide empty cream gap instead of sitting on the actual
   boundary, unlike the flush .how-it-works::before/::after seams above. */
.site-footer {
  background-color: var(--tby-navy);
  background-image: url("/constellation-navy.svg?v=13");
  background-repeat: repeat;
  background-position: center;
  background-size: 1600px 1600px;
  color: var(--tby-cream);
}

.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2.5rem 1rem;
  text-align: center;
}

.footer-tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.3rem;
  letter-spacing: 0.3px;
  color: var(--tby-gold-dark);
  margin: 0 0 1.25rem;
}

.footer-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  font-size: 0.85rem;
  margin-bottom: 1.25rem;
}

.footer-links a {
  text-decoration: none;
  color: var(--tby-cream);
  opacity: 0.85;
}

.footer-links a:hover {
  opacity: 1;
  color: var(--tby-gold);
}

.footer-signup {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  text-align: left;
  padding: 1.75rem 0;
  margin-bottom: 1.5rem;
  border-top: 1px solid rgba(245, 240, 232, 0.1);
  border-bottom: 1px solid rgba(245, 240, 232, 0.1);
}

.footer-signup-title {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 500;
  color: var(--tby-cream);
  margin: 0 0 0.3rem;
}

.footer-signup-note {
  font-size: 0.85rem;
  font-weight: 300;
  color: rgba(245, 240, 232, 0.5);
  margin: 0;
}

.footer-signup-form {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.footer-signup-form input {
  background: rgba(245, 240, 232, 0.06);
  border: 1px solid rgba(245, 240, 232, 0.2);
  border-radius: 8px;
  padding: 0.65rem 1rem;
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--tby-cream);
  min-width: 220px;
}

.footer-signup-form input::placeholder {
  color: rgba(245, 240, 232, 0.4);
}

.footer-signup-form input:focus {
  outline: none;
  border-color: var(--tby-gold);
}

.footer-signup-status {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--tby-gold);
  margin: 0;
}

.footer-social {
  display: flex;
  justify-content: center;
  gap: 0.85rem;
  margin-bottom: 1.5rem;
}

.footer-social-link {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(245, 240, 232, 0.5);
  border: 1px solid rgba(245, 240, 232, 0.15);
  border-radius: 50%;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.footer-social-link svg {
  width: 17px;
  height: 17px;
}

.footer-social-link .fs-icon-line {
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.footer-legal-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1rem;
  font-size: 0.7rem;
  margin-bottom: 1rem;
}

.footer-legal-links a {
  text-decoration: none;
  color: rgba(245, 240, 232, 0.45);
}

.footer-legal-links a:hover {
  color: var(--tby-gold);
}

.footer-social-link .fs-icon-dot {
  fill: currentColor;
}

.footer-social-link:hover {
  color: var(--tby-gold);
  border-color: rgba(201, 168, 76, 0.4);
}

@media (max-width: 600px) {
  .footer-signup {
    flex-direction: column;
    align-items: flex-start;
  }
}

.footer-copyright {
  font-size: 0.75rem;
  opacity: 0.6;
  margin: 0;
}

/* --- Hero --- */

/* Round-10 rebuild: replaces the round-7/8 side-by-side split (text column
   left, boxed photo right) with a single full-bleed photo and the copy
   overlaid directly on top, per the reference mockup. .hero is now the
   photo container itself (not a layout row) - aspect-ratio stays
   5602/3195 so the existing letterbox-crop math on the image (below)
   keeps working unchanged; only .hero-content sits on top via z-index. */
.hero {
  position: relative;
  overflow: hidden;
  width: 100%;
  aspect-ratio: 5602 / 3195;
  display: flex;
  align-items: center;
}

/* Same crop trick as the old .hero-visual-img, unchanged: homepage-hero.png
   has an opaque black letterbox baked in (real content is 5602x3195 of the
   6400x4000 canvas), removed by scaling up 6400/5602 and centering.
   Round-14: "whole photo reads dark/muted, not just the edges" - traced
   through .hero::before below and confirmed the navy scrim is fully
   transparent past 60% across, so the right 40% of the photo has zero
   overlay darkening on it at all. That portion reading dim is the raw
   photo's own tonal quality (a candlelit navy-toned scene), not the
   overlay math - so a filter belongs on the image itself, not the
   gradients.
   Round-15: applying that filter uniformly (as round 14 did) also
   brightened the left side under the headline, giving the navy scrim more
   visual noise to suppress than before. Moved the filter off this base
   layer entirely onto a second stacked copy (.hero-bg-img-enhanced,
   directly below) that's gradient-masked to only show through where the
   scrim isn't doing contrast work. This layer stays exactly as it always
   was - the true, unboosted photo, always fully visible as the base. */
.hero-bg-img {
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 114.25%;
  max-width: 114.25%;
  height: auto;
  transform: translate(-50%, -50%);
  border: none;
}

/* Second copy of the same photo, stacked on top, boosted brightness/
   saturation like round 14 - but masked so the boost only shows through
   where the navy scrim (.hero::before) has already faded out. Mask stops
   (0%/32%/60%) deliberately mirror the scrim's own gradient stops: fully
   masked-off (base layer shows through unboosted) wherever the scrim is
   still doing meaningful contrast work, ramping in exactly as the scrim
   ramps out, fully boosted only past 60% where the scrim is already zero.
   Fixes the original "right side too dim" complaint without re-brightening
   the left side underneath the headline. */
.hero-bg-img-enhanced {
  filter: brightness(1.12) saturate(1.15);
  mask-image: linear-gradient(to right, transparent 0%, transparent 32%, black 60%, black 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, transparent 32%, black 60%, black 100%);
}

/* Two jobs in one layer: (1) the previously-approved cream fade at the
   very top/bottom, where the hero meets the header/next section - kept
   exactly as confirmed working in round 9, just re-scoped from
   .hero-visual to .hero itself. (2) a navy scrim, darkest under the text
   on the left and clearing by 60% across, so the light-colored copy stays
   readable against the photo per the mockup. Both are additive gradient
   layers over the photo - no oval/rounded-rect shape risk since these are
   plain edge-aligned gradients, not a mask.
   Round-13: the top/bottom fade specifically (not the left-right text
   scrim, confirmed correct as-is) read as too heavy overall - it was
   fading a full 8% band at each edge all the way to fully opaque cream.
   Halved the affected band (8% -> 4%) and capped the peak at 70% opacity
   instead of 100%, so the edge treatment stays a soft lighten rather than
   a heavy wash, touching less of the photo.
   Round-16: "one more small adjustment" - a bit more separation directly
   behind the headline specifically, not another full-image change. Added
   a third layer, a soft radial patch approximately centered on where the
   headline sits (20% from left, 38% from top - the exact spot shifts
   slightly with viewport width since .hero-content's own max-width caps
   its growth, so this is an approximation, not pixel-exact). Sits between
   the cream edge-fade and the main scrim in paint order; soft-edged
   enough to be forgiving of the approximation. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(245, 240, 232, 0.7) 0%, rgba(245, 240, 232, 0) 4%, rgba(245, 240, 232, 0) 96%, rgba(245, 240, 232, 0.7) 100%),
    radial-gradient(ellipse 32% 42% at 20% 38%, rgba(10, 22, 40, 0.28) 0%, rgba(10, 22, 40, 0) 100%),
    linear-gradient(to right, rgba(10, 22, 40, 0.62) 0%, rgba(10, 22, 40, 0.32) 32%, rgba(10, 22, 40, 0) 60%);
}

.hero-content {
  position: relative;
  z-index: 2;
  max-width: 560px;
  padding: 0 1.5rem 0 calc(max(0px, (100vw - 1200px) / 2) + 1.5rem);
  color: #F5F0E8;
}

.hero h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: -1.5px;
  color: #F5F0E8;
  margin: 0 0 0.9rem;
}

/* Switched from --tby-gold-dark to the brighter --tby-gold for this one
   spot - gold-dark is tuned for text on the light cream page background;
   against the new dark navy scrim, the brighter token holds contrast
   better. Still an existing brand token, not a new color. */
.hero-tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 1.2rem;
  color: var(--tby-gold);
  margin: 0 0 1.25rem;
  letter-spacing: 0.2px;
}

.hero .hero-subheadline {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.1rem;
  line-height: 1.6;
  color: rgba(245, 240, 232, 0.82);
  margin: 0 0 2rem;
  max-width: 440px;
}

/* Round-10: "move the button further right" - added left margin so the CTA
   sits offset from the text above it rather than flush with the same left
   edge as the headline. */
.hero-cta-row {
  margin: 0 0 1.75rem 0.75rem;
}

/* Card icon + accent bar, shared by moment cards and subcategory cards. */
.card-icon {
  width: 22px;
  height: 22px;
}

.card-icon .card-icon-line {
  stroke: var(--tby-teal);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.card-accent {
  display: block;
  width: 20px;
  height: 2px;
  background: rgba(29, 158, 117, 0.55);
  margin: 0.6rem 0 0.1rem;
}

/* Gold default / teal-on-hover CTA, scoped to these cards only - white
   text and a 6px radius, distinct from the sitewide .btn-gold (navy
   text, 8px radius) used everywhere else. */
.subcategory-card .btn {
  background: var(--tby-gold);
  color: #fff;
  border-radius: 6px;
  box-shadow: none;
  transition: background 0.15s ease;
}

.subcategory-card .btn:hover {
  background: var(--tby-teal);
  box-shadow: none;
  transform: none;
}

/* --- FAQ --- */

.faq {
  max-width: 800px;
  margin: 0 auto;
  padding: 1rem 1.5rem 4.5rem;
}

.faq h2 {
  text-align: center;
  font-weight: 600;
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  letter-spacing: -0.3px;
  margin: 0 0 2.5rem;
}

/* Same card panel treatment as .moment-card/.theme-preview elsewhere
   (background, border, radius, soft shadow), and the same linen-weave +
   constellation texture used sitewide on the body, layered here instead
   of on body since the panel's own #FBF9F5 background would otherwise
   hide it - same data URIs/opacity, just repainted on this element. */
.faq-list {
  background-color: #FBF9F5;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Cpath d='M0 0L6 6M6 0L0 6' stroke='%230A1628' stroke-width='0.6' opacity='0.015'/%3E%3C/svg%3E"),
    url("/constellation-cream.svg?v=13");
  background-repeat: repeat, repeat;
  background-position: center top, center top;
  background-size: 6px 6px, 1600px 1600px;
  border: 1px solid rgba(201, 168, 76, 0.3);
  border-radius: 20px;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
  padding: 0.25rem 2rem;
}

.faq-item {
  border-bottom: 1px solid rgba(10, 22, 40, 0.08);
  padding: 1.85rem 0;
}

.faq-item:last-child {
  border-bottom: none;
}

.faq-item summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-weight: 500;
  font-size: 1.05rem;
  color: var(--tby-navy);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

/* Thin-line icon language (matches .card-icon-line/.theme-badge's circular
   treatment elsewhere) instead of a plain +/- glyph. A single element
   rotated 45deg turns the plus into an x, so the state change is one
   smooth transform transition rather than a discrete content swap. */
.faq-toggle-icon {
  position: relative;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(201, 168, 76, 0.4);
  transition: transform 0.25s ease, border-color 0.2s ease;
}

.faq-toggle-icon::before,
.faq-toggle-icon::after {
  content: '';
  position: absolute;
  background: var(--tby-gold-dark);
  transition: background 0.2s ease;
}

.faq-toggle-icon::before {
  left: 50%;
  top: 26%;
  bottom: 26%;
  width: 1.5px;
  transform: translateX(-50%);
}

.faq-toggle-icon::after {
  top: 50%;
  left: 26%;
  right: 26%;
  height: 1.5px;
  transform: translateY(-50%);
}

.faq-item[open] .faq-toggle-icon {
  transform: rotate(45deg);
  border-color: var(--tby-teal);
}

.faq-item[open] .faq-toggle-icon::before,
.faq-item[open] .faq-toggle-icon::after {
  background: var(--tby-teal);
}

.faq-item p {
  margin: 1rem 0 0;
  font-weight: 300;
  color: rgba(10, 22, 40, 0.62);
  line-height: 1.65;
  max-width: 640px;
}

/* --- How it works --- */

/* Revised visual calibration (navy hero/bold panels only - NOT a general
   navy background rule): one dense gold constellation motif per panel,
   ~15-20 stars in loose ~60-80px-spaced clusters + short (<=~90px)
   connecting paths within each cluster, stretched to cover. Revised
   upward from an earlier ~6-8 star / full-span-length-lines pass that
   read as too sparse/scattered. Same gold/opacity tokens as before
   (fill 0.24, stroke 0.13) - only density changed. */
/* --- Section transitions: a shared gold hairline divider between
   same-background section boundaries, plus a soft cream<->navy fade
   at the top/bottom of any section that changes background color
   (currently just .how-it-works), so no boundary reads as a hard cut. --- */

.section-divider {
  max-width: 220px;
  height: 1px;
  margin: 0 auto;
  background: linear-gradient(90deg, transparent, rgba(201, 168, 76, 0.4), transparent);
}

/* Constellation density fix (round 2): the previous version used a single
   1200x500 canvas stretched via background-size:100% 100% (background-
   repeat: no-repeat) to fill the section's actual rendered dimensions.
   That stretch is non-uniform and grows with viewport width, so on
   anything wider than ~1200px the 60-90px star spacing got diluted back
   toward looking sparse - the star count (18) and opacity had already
   been raised per the prior instruction, but the stretch was quietly
   undoing it. Switched to a small tile (300x300, repeated via background-
   repeat instead of stretched) so spacing stays pixel-true at any section
   width.
   Round-5: even pixel-true, a 300x300 tile with only 9 fixed stars still
   visibly repeats several times across a normal viewport - replaced with
   the same generated randomized 1600x1600 field used on cream sections
   above (navy-opacity variant: /constellation-navy.svg), so it reads as
   one continuous irregular star field instead of a tile. */
.how-it-works {
  position: relative;
  background-color: var(--tby-navy);
  background-image: url("/constellation-navy.svg?v=13");
  background-repeat: repeat;
  background-position: center;
  background-size: 1600px 1600px;
  color: var(--tby-cream);
  max-width: none;
  margin: 0;
  padding: 4.5rem 1.5rem 5rem;
}

/* A direct navy-to-cream gradient was tried first (per the standing
   instruction to attempt that before falling back) but still reads as a
   muddy gray band: both colors are low-saturation, so ANY linear RGB
   blend between them passes through genuinely gray midtones - not a
   "transparent" keyword artifact, a property of blending two desaturated
   colors. Falling back to the alternative: a thin decorative constellation
   line that sits ON the hard color seam (no blending) rather than trying
   to fade across it. Reused at every navy<->cream boundary on the page -
   see .constellation-seam.
   The line itself must stay perfectly straight (a single H command, all
   dots at the same y) - an earlier version zigzagged between varying y
   values per point and read as a rendering glitch, not a deliberate
   accent, once tiled edge-to-edge across the full page width. */
.how-it-works::before,
.how-it-works::after,
.constellation-seam {
  background-repeat: repeat-x;
  background-position: center;
  background-size: 200px 24px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='24'%3E%3Cg stroke='%23C9A84C' stroke-width='0.8' opacity='0.35' fill='none'%3E%3Cpath d='M0 12H200'/%3E%3C/g%3E%3Cg fill='%23C9A84C' opacity='0.55'%3E%3Ccircle cx='20' cy='12' r='1.4'/%3E%3Ccircle cx='70' cy='12' r='1.6'/%3E%3Ccircle cx='120' cy='12' r='1.4'/%3E%3Ccircle cx='170' cy='12' r='1.6'/%3E%3C/g%3E%3C/svg%3E");
}

.how-it-works::before,
.how-it-works::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 24px;
  pointer-events: none;
  z-index: 3;
}

.how-it-works::before {
  top: -12px;
}

.how-it-works::after {
  bottom: -12px;
}

/* Standalone version of the same seam graphic, for boundaries between two
   sibling elements rather than a pseudo-element straddling its own parent's
   edge (e.g. the cream FAQ section into the navy footer). Negative margins
   let it overlap 12px into each neighboring section, same straddle effect
   as the .how-it-works pseudo-elements above. */
.constellation-seam {
  height: 24px;
  margin: -12px 0;
  position: relative;
  z-index: 3;
  pointer-events: none;
}

.how-it-works-inner {
  position: relative;
  z-index: 2;
  max-width: 1100px;
  margin: 0 auto;
  text-align: left;
}

.how-it-works-label {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.how-it-works-rule {
  width: 32px;
  height: 1px;
  background: rgba(201, 168, 76, 0.4);
  flex-shrink: 0;
}

/* Round-5 comparison (not yet decided - see Brianna's teal-vs-gold call):
   gold at 0.7 opacity reads low-contrast on both backgrounds this line
   actually appears on - navy (How It Works) and cream (Events carousel,
   which never got the theme-explorer's cream-only color fork below) - so
   this is a temporary teal test, screenshotted next to the gold version
   for a side-by-side decision, not a locked-in change yet. */
.how-it-works-eyebrow {
  position: relative;
  display: inline-block;
  padding-bottom: 8px;
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 500;
  color: var(--tby-teal);
  letter-spacing: 2px;
  text-transform: uppercase;
}

/* Locked calibration (item 4c): thin teal underline beneath eyebrow labels. */
.how-it-works-eyebrow::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 32px;
  height: 2px;
  background: var(--tby-teal);
}

.how-it-works h2 {
  font-weight: 600;
  font-size: clamp(2rem, 4.5vw, 3.25rem);
  letter-spacing: -0.5px;
  line-height: 1.08;
  color: var(--tby-cream);
  margin: 0 0 3.5rem;
  max-width: 700px;
}

.how-it-works-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
}

@media (max-width: 700px) {
  .how-it-works-steps {
    grid-template-columns: 1fr;
  }
}

.step-number {
  display: block;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: 4rem;
  line-height: 1;
  color: var(--tby-gold);
  opacity: 0.75;
  margin-bottom: 0.5rem;
}

.step-number::after {
  content: '';
  display: block;
  width: 32px;
  height: 1px;
  background: rgba(201, 168, 76, 0.4);
  margin-top: 1.1rem;
}

.how-it-works-steps h3 {
  font-weight: 500;
  font-size: 1.25rem;
  color: var(--tby-cream);
  margin: 0 0 0.6rem;
}

.how-it-works-steps p {
  font-weight: 300;
  color: rgba(245, 240, 232, 0.55);
  font-size: 0.9rem;
  line-height: 1.65;
  margin: 0;
}

.how-it-works-cta {
  margin-top: 3.5rem;
  display: flex;
  align-items: center;
  gap: 2rem;
  flex-wrap: wrap;
}

.how-it-works-note {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  color: rgba(245, 240, 232, 0.4);
}

/* --- Theme explorer: interactive extension of How It Works.
   NOTE for whoever revisits this: rebalanced as of the 2026-07-16 asset
   delivery to 2 kids themes (space, undersea), 2 bridal themes
   (enchantedbridal, starlitbridal), and 2 corporate themes (teammilestone,
   clientappreciation - both marked comingSoon in theme-explorer.js), plus
   a non-theme "Design Your Own" tile that routes to /start-designing instead
   of swapping in preview visuals. The old kids-only roster (enchantedforest,
   unicorn, dinosaur, safari) was retired - see [[project_themedbyyou_theme_names]]
   memory for the display-name history if those come back. To add another
   theme, extend the THEMES map in theme-explorer.js and drop matching
   badge-/phone-/carousel-/*-thumb-* files in public/ following the
   existing naming convention. --- */

.theme-explorer-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 3rem 1.5rem 6rem;
  text-align: left;
}

.theme-explorer-inner .how-it-works-rule {
  /* gold-on-navy tokens read too faint on this section's cream
     background, so darken them here rather than fork new classes.
     Round-5 test: eyebrow TEXT color no longer forked here - the teal
     test above is being tried uniformly across cream+navy instead. */
  color: rgba(10, 22, 40, 0.55);
}

.theme-explorer-inner .how-it-works-rule {
  background: rgba(10, 22, 40, 0.25);
}

.theme-explorer-inner h2 {
  font-weight: 600;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  letter-spacing: -0.4px;
  line-height: 1.12;
  color: var(--tby-navy);
  margin: 0 0 0.6rem;
}

.theme-explorer-subhead {
  color: rgba(10, 22, 40, 0.55);
  font-size: 0.95rem;
  margin: 0 0 2.5rem;
}

/* --- Theme search bar (the actual interactive element - theme badges
   populate this via typewriter animation rather than a passive label) --- */

/* Round-7: sized up ~20% across this whole block (max-width, icon, text,
   submit button) to rebalance against the phone mockup, which jumped to
   640px in round 5 while this copy stayed at its pre-round-5 size - next
   to the much bigger phone it now read as undersized. */
.theme-search-bar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  max-width: 680px;
  margin: 0 0 2.5rem;
  background: #fff;
  border: 1px solid rgba(201, 168, 76, 0.35);
  border-radius: 999px;
  padding: 0.65rem 0.65rem 0.65rem 1.5rem;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
}

.search-bar-icon {
  width: 21px;
  height: 21px;
  flex-shrink: 0;
}

.search-bar-textwrap {
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--tby-navy);
  white-space: nowrap;
  overflow: hidden;
}

.search-bar-cursor {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  background: var(--tby-gold);
  vertical-align: -0.15em;
  animation: theme-cursor-blink 1s step-end infinite;
}

.search-bar-submit {
  width: 48px;
  height: 48px;
  padding: 0;
  border-radius: 50%;
  background: var(--tby-gold);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s ease;
}

.search-bar-submit:hover {
  background: var(--tby-gold-dark);
}

.search-bar-submit svg {
  width: 19px;
  height: 19px;
}

/* Bug fix (fix-batch): a `stroke="#hex"` PRESENTATION ATTRIBUTE directly on
   an inline SVG path (rather than stroke set via a CSS class, as every
   other icon on the site does it - see .ps-icon-line/.card-icon-line/etc.)
   makes the browser compute the parent <svg>'s own width as a fraction of
   a pixel, shrinking the whole icon to near-invisible regardless of the
   width/height set on the svg element - this is what read as "pagination
   dots" instead of arrows. Moving stroke (and stroke-width/linecap/
   linejoin) into a CSS class, matching the working convention used
   everywhere else, is the fix - not a sizing tweak on the svg itself. */
.search-bar-submit-icon {
  stroke: var(--tby-navy);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.theme-badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-bottom: 3.5rem;
}

/* Round-7: 76px -> 92px, alongside the search-bar/copy scale-up above -
   same "rebalance against the round-5 640px phone" reason.
   Round-20: dropped the 7px padding (was insetting the 6 photo badges'
   artwork inside the circle, while .theme-badge--custom - solid navy
   background, no image - naturally filled edge to edge regardless of that
   same padding, reading as inconsistent scale across the row). Custom tile
   gets its own explicit padding below so removing it here doesn't cramp
   its icon+label. object-fit switched contain -> cover on the image itself
   so it truly fills the full circle (cropping any excess) rather than
   leaving letterbox gaps if a badge photo's aspect ratio isn't perfectly
   square. */
.theme-badge {
  background: #FBF9F5;
  border: 2px solid transparent;
  border-radius: 50%;
  width: 92px;
  height: 92px;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(10, 22, 40, 0.06);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.theme-badge img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

.theme-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(10, 22, 40, 0.1);
}

.theme-badge.active {
  border-color: var(--tby-gold);
  box-shadow: 0 0 0 4px rgba(201, 168, 76, 0.16), 0 6px 18px rgba(10, 22, 40, 0.1);
}

/* Team Milestone / Client Appreciation badges are visually identical to
   the live themes - per the fix-batch spec, Coming Soon treatment belongs
   only at the box/card level (theme-preview-soon-chip below, and
   .events-carousel-card--soon), not on the badges themselves. */

/* "Design Your Own" is always shown as a 7th, equal-weight tile - it
   isn't a themed preview, so it gets its own icon rather than a badge
   photo, but matches the same circle size/spacing as the others.
   Round-20: explicit padding added here since the shared 7px padding on
   .theme-badge was removed above - this tile has no image, just an
   icon+label that still needs room to breathe inside the circle. */
.theme-badge--custom {
  background: var(--tby-navy);
  flex-direction: column;
  gap: 2px;
  padding: 7px;
}

.theme-badge-custom-icon {
  width: 20px;
  height: 20px;
}

.theme-badge-custom-label {
  font-family: var(--font-body);
  font-size: 0.6rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--tby-cream);
  text-align: center;
}

.theme-preview-soon-chip {
  display: block;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--tby-gold-dark);
  margin: 0 0 0.75rem;
}

.phone-preview-fab.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Deliberately no card background/border/shadow here (fix-batch spec):
   this panel used to sit in a separate off-white rounded card, reading as
   "boxed" against the section's own textured cream background instead of
   sitting seamlessly on it. Phone column widened 260px -> 340px -> 440px
   across two incremental rounds of the same spec ("phone mockup images
   still too small") and still read as undersized - round 5 asked for a
   substantial, non-incremental jump instead, so this went straight to
   640px (+45% over 440px) rather than another small step. */
.theme-preview {
  display: grid;
  grid-template-columns: 640px 1fr;
  gap: 4rem;
  align-items: start;
  padding: 2rem 0 0;
}

/* Bumped from 700px to 1150px alongside the round-5 phone-column widen
   (440px -> 640px) - below ~1150px viewport, a 2-column layout would
   squeeze the info column (text + 5-thumb grid) too tight before ever
   reaching this breakpoint. Stacking sooner just means the much bigger
   phone gets its own full-width row, which fits the "layered into the
   scene" spec fine on its own. Capped at 640px (its 2-column width) so it
   doesn't balloon past the intended size on mid-width viewports that are
   still wide enough to look odd stacked-and-uncapped. */
@media (max-width: 1150px) {
  .theme-preview {
    grid-template-columns: 1fr;
  }

  .theme-preview-phone-wrap {
    max-width: 640px;
    margin: 0 auto;
  }
}

.theme-preview-phone-wrap {
  position: relative;
}

/* Clips the per-theme transform:scale() zoom (see .theme-preview-phone-img
   below) to the frame - kept as its own element rather than putting
   overflow:hidden on .theme-preview-phone-wrap itself, since the wrap
   also contains .phone-preview-fab, which is deliberately positioned
   partway outside the frame (bottom:-14px; right:-14px) and would get
   clipped too if the wrap itself hid overflow. */
.theme-preview-phone-clip {
  overflow: hidden;
}

/* phone-[theme].png already has a complete phone mockup (frame, notch,
   screen) rendered into the photo itself, with a transparent background
   outside the phone shape - it's a finished asset like the badge/thumb
   images, not a bare scene meant to be composited into a coded frame.
   An earlier version wrapped it in a CSS-built bezel + notch, producing
   two nested phone frames. Place the image directly - no wrapper
   frame/background needed since the transparency already does the work.
   Round-6 fix: the "aspect ratios cluster tightly enough" assumption
   above was wrong in the way that actually mattered - re-measured each
   theme's opaque bounding box precisely (scripted alpha-channel scan, not
   eyeballing) and the phone content's WIDTH fraction of the 2400x1200
   canvas ranges 53.9%-60.6% across themes, not a tight cluster. A single
   shared crop (the old 1430/780 aspect-ratio, itself stale from before
   this asset batch) crops every theme by the same absolute amount
   regardless of how much margin that theme's source photo actually has
   around its phone, so the rendered phone visibly changes size switching
   themes. Real fix: this box now maps the full 2400x1200 canvas 1:1 (no
   CSS-level crop at all), and a small per-theme `transform: scale()`
   (set in theme-explorer.js from these same measurements, target ~58%
   width fraction) zooms each theme in or out by just enough to normalize
   the phone to one consistent apparent size. overflow:hidden on the wrap
   clips the small overscan from themes that need to zoom in. */
.theme-preview-phone-img {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  transition: opacity 0.3s ease;
}

.theme-preview-phone-img.is-fading {
  opacity: 0;
}

.phone-preview-fab {
  position: absolute;
  bottom: -14px;
  right: -14px;
  width: 52px;
  height: 52px;
  padding: 0;
  border-radius: 50%;
  background: var(--tby-gold);
  border: 3px solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 18px rgba(10, 22, 40, 0.2);
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease;
}

.phone-preview-fab:hover {
  transform: translateY(-2px);
  background: var(--tby-gold-dark);
}

.phone-preview-fab svg {
  width: 22px;
  height: 22px;
}

/* Same inline-stroke-attribute bug fix as .search-bar-submit-icon above. */
.phone-fab-icon-line {
  stroke: var(--tby-navy);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.phone-fab-icon-line--thick {
  stroke-width: 1.6;
}

/* Round-7: eyebrow/name/soon-chip all scaled up alongside the search bar
   and badges above - same rebalance against the round-5 640px phone. */
.theme-preview-eyebrow {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--tby-teal);
  margin-bottom: 0.5rem;
}

.theme-preview-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.8rem, 3.4vw, 2.5rem);
  color: var(--tby-navy);
  margin: 0 0 0.5rem;
  min-height: 1.3em;
}

@keyframes theme-cursor-blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* Round-17: removed the connector-line diagram entirely (was 5 individual
   curved SVG paths from the "Now previewing" block down to the thumbnail
   row) after 5 rounds of curve-math adjustments (garland droop -> fan
   spacing -> tangent-sweep tuning -> equal-segment-length fix -> overshoot)
   never landed - reported as reading "erratic"/"more claw than garland".
   Deliberate scope change per spec: a fragile multi-line effect that
   hasn't worked in 5 attempts isn't worth a 6th math attempt - replaced
   with a single small centered icon as the visual link instead. Full
   history of the abandoned approach is in git log/blame on this file if
   ever needed again. */
.theme-preview-link {
  display: flex;
  justify-content: center;
  margin: 1.75rem 0 2.5rem;
  color: var(--tby-teal);
}

.theme-preview-link svg {
  width: 20px;
  height: 20px;
}

.theme-thumbs {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1.1rem;
  transition: opacity 0.3s ease;
}

.theme-thumbs.is-fading {
  opacity: 0;
}

@media (max-width: 560px) {
  .theme-thumbs {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Round-16: this is almost certainly the "5 item thumbnail cards" reported
   plain/blending-in across rounds 14-15 - .swi-tile (the 6-item "See
   what's inside" grid) was fixed instead by mistake, a different section
   entirely. These thumbs had zero card treatment (no background/border/
   shadow at all). Generated dynamically via theme-explorer.js as bare
   <img class="img-card"> with no wrapper div, so the frame is built
   directly on the img using border-box padding (global * { box-sizing:
   border-box } makes aspect-ratio:1/1 apply to the padded box, and
   object-fit:cover then fills just the inner content area) rather than
   adding a wrapper element. Deliberately more assertive than .swi-tile's
   values (white instead of near-white, stronger border/shadow) given the
   previous subtle attempt may not have been visible even on the right
   element. Specificity note: .theme-thumbs img (0,1,1) beats the shared
   .img-card class (0,1,0) from theme-explorer.js, so this cleanly
   overrides img-card's own border-radius/shadow for just this grid. */
.theme-thumbs img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #FFFFFF;
  border: 1px solid rgba(201, 168, 76, 0.5);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 3px 14px rgba(10, 22, 40, 0.1);
}

/* --- Events carousel ("Events we're dreaming up"): a separate showcase
   strip from the How It Works theme explorer above - static lifestyle
   images (carousel-[theme].png, 1600x1000) in a horizontal scroll-snap
   track rather than an interactive swap. "Design Your Own" is always the
   7th, equal-weight card so it's never presented as secondary to the
   6 curated themes. --- */

.events-carousel {
  max-width: 1080px;
  margin: 0 auto;
  padding: 2rem 1.5rem 3rem;
}

.events-carousel-inner {
  text-align: left;
}

.events-carousel h2 {
  font-weight: 600;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  letter-spacing: -0.4px;
  line-height: 1.12;
  color: var(--tby-navy);
  margin: 0 0 0.6rem;
}

.events-carousel-subhead {
  color: rgba(10, 22, 40, 0.55);
  font-size: 0.95rem;
  margin: 0 0 2rem;
}

.events-carousel-track {
  display: flex;
  gap: 1.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 0.5rem;
  scrollbar-width: none;
}

.events-carousel-track::-webkit-scrollbar {
  display: none;
}

.events-carousel-card {
  position: relative;
  flex: 0 0 340px;
  scroll-snap-align: start;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.06);
  background: #FBF9F5;
  text-decoration: none;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.events-carousel-card:hover {
  box-shadow: 0 8px 22px rgba(10, 22, 40, 0.12);
  transform: translateY(-2px);
}

.events-carousel-img {
  display: block;
  width: 100%;
  aspect-ratio: 1600 / 1000;
  object-fit: cover;
  transition: transform 0.35s ease;
}

.events-carousel-card:hover .events-carousel-img {
  transform: scale(1.06);
}

.events-carousel-caption {
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.15rem;
  color: var(--tby-navy);
  padding: 1rem 1.1rem 0.9rem;
  position: relative;
}

/* Thin gold accent rule over the caption - same visual language as
   .card-accent on the lane cards below, so this card grid doesn't read
   as flatter/less designed than the rest of the page. */
.events-carousel-caption::before {
  content: '';
  position: absolute;
  top: 0;
  left: 1.1rem;
  width: 28px;
  height: 2px;
  background: var(--tby-gold);
}

/* Coming Soon pattern (standing mechanic, round-4 spec): live and
   coming-soon cards share identical layout/sizing - the only difference
   is this muted color treatment. No per-card pill/crossed-out/warning
   styling; the single .coming-soon-note near the section subhead is what
   labels the group. See .badge-new below for the companion mechanic. */
.events-carousel-card--soon .events-carousel-img {
  filter: saturate(0.4) brightness(1.02);
}

.coming-soon-note {
  color: rgba(10, 22, 40, 0.4);
  font-style: italic;
}

/* Companion to the Coming Soon pattern above: flags a freshly-launched
   theme rather than an unavailable one, so it uses the brand gold instead
   of the muted/navy Coming Soon language. Not applied to any theme yet -
   ready to drop onto a badge/card the moment one actually launches. */
.badge-new {
  display: inline-block;
  background: var(--tby-gold);
  color: var(--tby-navy);
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
}

.events-carousel-card--custom {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(201, 168, 76, 0.5);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.events-carousel-card--custom:hover {
  box-shadow: 0 6px 18px rgba(10, 22, 40, 0.1);
  transform: translateY(-2px);
}

.events-carousel-custom-visual {
  width: 100%;
  aspect-ratio: 1600 / 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--tby-navy);
}

.events-carousel-custom-visual svg {
  width: 48px;
  height: 48px;
}

.events-carousel-nav {
  display: flex;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

/* Root cause of the "pagination dots" report: <button> carries the UA
   stylesheet's own default padding (~0.6em/1.2em, i.e. ~10px/19px at this
   font-size) unless reset. That ate nearly the full 42px box, squeezing
   the 18px icon down to a sliver - it was never about the icon markup.
   .theme-badge (a button too) happened to set its own 6px padding and so
   never showed the bug; these never got an explicit reset. Same fix
   applied to .search-bar-submit and .phone-preview-fab below.
   Round-2 fix-batch: restyled from a flat cream/hairline circle (read as
   "bland") to the same solid-gold-circle language already used for
   .phone-preview-fab and .search-bar-submit, so all three "tap this
   circle" affordances on the page read as one consistent, branded
   control instead of one polished pair plus a plain outlier. */
.events-carousel-btn {
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 50%;
  background: var(--tby-gold);
  border: none;
  box-shadow: 0 4px 14px rgba(10, 22, 40, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}

.events-carousel-btn:hover {
  background: var(--tby-gold-dark);
  transform: translateY(-2px);
}

.events-carousel-btn svg {
  width: 18px;
  height: 18px;
}

/* Same inline-stroke-attribute bug fix as .search-bar-submit-icon above -
   this is the "pagination dots not intuitive" report: the arrows were
   always there, just rendering at a near-zero width. */
.events-carousel-btn-icon {
  stroke: var(--tby-navy);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Image placeholders (About page - marks slots for real photography) --- */

.img-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  background: rgba(10, 22, 40, 0.04);
  border: 1.5px dashed rgba(10, 22, 40, 0.2);
  border-radius: 10px;
  color: rgba(10, 22, 40, 0.4);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  text-align: center;
  padding: 1rem;
}

/* --- Gallery teaser + gallery page tiles --- */

.gallery-teaser {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1rem 1rem 3rem;
  text-align: center;
}

.gallery-teaser h2 {
  font-weight: 600;
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  letter-spacing: -0.3px;
  margin-bottom: 2rem;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

@media (max-width: 800px) {
  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.gallery-tile {
  border-radius: 10px;
  aspect-ratio: 1;
  display: flex;
  align-items: flex-end;
  padding: 0.75rem;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: left;
  background: linear-gradient(135deg, var(--tby-gold), var(--tby-navy));
}

.gallery-tile:nth-child(4n+2) {
  background: linear-gradient(135deg, var(--tby-gold-dark), var(--tby-navy));
}

.gallery-tile:nth-child(4n+3) {
  background: linear-gradient(135deg, var(--tby-navy), var(--tby-gold));
}

.gallery-tile:nth-child(4n+4) {
  background: linear-gradient(135deg, #b8963f, var(--tby-gold));
}

.gallery-tile.gallery-photo {
  background: none;
  padding: 0;
  overflow: hidden;
}

.gallery-teaser .btn {
  margin-top: 2rem;
}

/* --- Product showcase ("See what's inside"): revived as a real photo
   section (2026-07-16 rebalanced asset delivery) using the 6 homepage-
   thumb-*.png product photos - the trust-feature-row below still carries
   its own icon set separately, this is a fuller visual showcase above it. --- */

.see-whats-inside {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1rem 1.5rem 4rem;
  text-align: center;
}

.see-whats-inside h2 {
  font-weight: 600;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  letter-spacing: -0.4px;
  color: var(--tby-navy);
  margin: 0 0 0.6rem;
}

.see-whats-inside-subhead {
  color: rgba(10, 22, 40, 0.55);
  font-size: 0.95rem;
  margin: 0 0 2.5rem;
}

.see-whats-inside-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.25rem;
}

@media (max-width: 900px) {
  .see-whats-inside-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 500px) {
  .see-whats-inside-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Round-14: these tiles had no card treatment of their own - just a bare
   image (only .img-card's own subtle 0.06-opacity shadow) sitting
   directly on the page's cream texture, which read as "lost"/blending
   into the background. Added the same panel treatment used elsewhere on
   the page (.theme-badge/.moment-card: #FBF9F5 background, thin gold
   border, soft shadow) so each tile reads as a distinct card. */
.swi-tile {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: #FBF9F5;
  border: 1px solid rgba(201, 168, 76, 0.25);
  border-radius: 12px;
  padding: 0.85rem 0.85rem 1rem;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
}

.swi-tile img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.swi-tile span {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 500;
  color: rgba(10, 22, 40, 0.6);
}

/* --- Trust/feature row: the 4 convenience stats (Ships in 5-7 days,
   etc.) only. Round-2 fix-batch: the product-line icons (Plates,
   Tumblers, Banners, Shirts, Coloring Books, Signs, Cups) that used to
   share this row were removed - they duplicated the real product photos
   in .see-whats-inside just above, and having both read as redundant.
   With only 4 items left, they get real presence (bigger icon, bigger
   text, more breathing room) instead of the small dense-row treatment
   sized for 11 items. --- */

.trust-feature-row {
  background: #FBF9F5;
  border-top: 1px solid rgba(201, 168, 76, 0.25);
  border-bottom: 1px solid rgba(201, 168, 76, 0.25);
  padding: 2.25rem 1.5rem;
}

.trust-feature-row-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.75rem 3.5rem;
}

.tf-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-body);
  font-size: 1.05rem;
  font-weight: 500;
  color: rgba(10, 22, 40, 0.7);
  white-space: nowrap;
  letter-spacing: 0.2px;
}

.tf-icon {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
}

.tf-icon .ps-icon-line {
  stroke: var(--tby-teal);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 700px) {
  .trust-feature-row-inner {
    gap: 1rem 1.5rem;
  }
}

/* --- Page hero (secondary pages: kids-party-box, specialty-boxes, etc.) --- */

.page-hero {
  text-align: center;
  padding: 3rem 1rem 2rem;
  max-width: 750px;
  margin: 0 auto;
}

.page-hero h1 {
  font-weight: 600;
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: -0.5px;
  margin: 0 0 0.75rem;
}

.page-hero p {
  font-weight: 300;
  color: rgba(10, 22, 40, 0.62);
  font-size: 1.05rem;
  line-height: 1.6;
  margin: 0;
}

/* Contextual "Custom Request" nudge on config pages (kids-party-box,
   specialty-boxes and its subcategories) - a quiet way out for customers
   whose need doesn't fit the standard box, without competing with the
   primary "Build your box" CTA above it. */
.custom-request-nudge {
  text-align: center;
  font-size: 0.9rem;
  font-weight: 300;
  color: rgba(10, 22, 40, 0.5);
  margin: 2.5rem 0 1rem;
}

.custom-request-nudge a {
  color: var(--tby-gold-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.custom-request-nudge a:hover {
  color: var(--tby-navy);
}

/* --- Order confirmation (checkout success) --- */

.confirmation-hero {
  text-align: center;
  max-width: 640px;
  margin: 0 auto;
  padding: 4.5rem 1rem 4rem;
}

.confirmation-hero h1 {
  font-weight: 600;
  font-size: clamp(2.25rem, 4.5vw, 3.25rem);
  line-height: 1.1;
  letter-spacing: -0.5px;
  margin: 0 0 0.75rem;
}

.confirmation-hero .hero-tagline {
  margin: 0 0 2rem;
}

.confirmation-copy {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.1rem;
  line-height: 1.7;
  color: rgba(10, 22, 40, 0.72);
  margin: 0 0 2.5rem;
}

/* --- Subcategory cards (specialty-boxes hub) --- */

.subcategory-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  max-width: 1200px;
  margin: 2rem auto 0;
  padding: 0 1rem;
}

@media (max-width: 900px) {
  .subcategory-grid {
    grid-template-columns: 1fr;
  }
}

.subcategory-card {
  background: #FBF9F5;
  border: 1px solid rgba(201, 168, 76, 0.4);
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
  border-radius: 12px;
  padding: 1.75rem;
  text-decoration: none;
  color: var(--tby-navy);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.subcategory-card:hover {
  box-shadow: 0 6px 20px rgba(10, 22, 40, 0.08);
  transform: translateY(-2px);
}

.subcategory-card h3 {
  font-family: var(--font-display);
  font-weight: 500;
  margin: 0;
  font-size: 16px;
  letter-spacing: -0.1px;
  color: var(--tby-navy);
}

.subcategory-card p {
  margin: 0;
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 400;
  line-height: 1.55;
  color: rgba(10, 22, 40, 0.5);
}

.subcategory-card .btn {
  margin-top: 0.75rem;
  align-self: flex-start;
}

/* --- Config form (category pages -> /design handoff) --- */

.config-form {
  max-width: 700px;
  margin: 2rem auto 0;
  padding: 0 1rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.config-form .field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.config-form label {
  font-weight: 600;
  font-size: 0.9rem;
}

.config-form input[type="text"],
.config-form input[type="email"],
.config-form input[type="tel"],
.config-form textarea,
.config-form select {
  padding: 0.75rem 0.9rem;
  font-size: 1rem;
  font-family: var(--font-body);
  border: 1.5px solid rgba(10, 22, 40, 0.14);
  border-radius: 8px;
  background: #fff;
  min-width: 0;
  width: 100%;
  transition: border-color 0.15s ease;
}

.config-form input[type="text"]:focus,
.config-form input[type="email"]:focus,
.config-form input[type="tel"]:focus,
.config-form textarea:focus,
.config-form select:focus {
  outline: none;
  border-color: var(--tby-gold);
}

.config-form textarea {
  resize: vertical;
}

.form-success {
  background: #eaf7f0;
  border: 1px solid var(--tby-gold);
  color: #0f4a35;
  padding: 1.25rem;
  border-radius: 8px;
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
}

.form-error {
  background: #fdecea;
  border: 1px solid #f5c2c0;
  color: #611a15;
  padding: 0.85rem;
  border-radius: 6px;
}

/* TEMPORARY: styling for the Phase 1D Stripe sandbox test tool on /cart.
   Remove alongside the markup once real products exist (see README). */
.dev-test-tools {
  max-width: 700px;
  margin: 0 auto 2rem;
  padding: 1rem 1.25rem;
  background: #fdecea;
  border: 1px dashed #c0392b;
  border-radius: 8px;
  color: #611a15;
  text-align: center;
}

.dev-test-tools p {
  margin: 0 0 0.75rem;
}

.product-checklist {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

@media (max-width: 600px) {
  .product-checklist {
    grid-template-columns: 1fr;
  }
}

.product-checklist label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  background: #fff;
  border: 1.5px solid rgba(10, 22, 40, 0.1);
  border-radius: 8px;
  padding: 0.6rem 0.85rem;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.product-checklist label:has(input:checked) {
  border-color: var(--tby-gold);
  background: rgba(201, 168, 76, 0.06);
}

.config-form .submit-row {
  display: flex;
  justify-content: flex-end;
}

/* --- Cart page --- */

.cart-items {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 2rem 0;
}

.cart-item {
  background: #fff;
  border: 1px solid rgba(10, 22, 40, 0.08);
  box-shadow: 0 6px 20px rgba(10, 22, 40, 0.05);
  border-radius: 10px;
  padding: 1rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.cart-item-info {
  flex: 1;
}

.cart-item-info .theme {
  font-size: 0.8rem;
  color: rgba(10, 22, 40, 0.6);
}

.cart-item-qty {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.cart-item-qty input {
  width: 3.5rem;
  padding: 0.35rem;
  text-align: center;
}

.cart-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 2px solid var(--tby-navy);
  padding-top: 1rem;
  font-size: 1.1rem;
  font-weight: 700;
}

.cart-checkout-note {
  background: #fff8e6;
  border: 1px solid var(--tby-gold);
  color: var(--tby-navy);
  padding: 1rem;
  border-radius: 8px;
  margin-top: 1.5rem;
  text-align: center;
}

.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: rgba(10, 22, 40, 0.6);
}

/* --- About page: story row (text + image) and team headshots --- */

.about-story-row {
  display: flex;
  align-items: center;
  gap: 2rem;
  margin-bottom: 1.25rem;
}

.about-story-row p {
  flex: 1 1 320px;
  margin-bottom: 0;
}

.about-story-row .img-placeholder,
.about-story-row img {
  flex: 1 1 260px;
  max-width: 320px;
  aspect-ratio: 4 / 3;
}

@media (max-width: 640px) {
  .about-story-row {
    flex-direction: column;
  }
}

.about-team {
  display: flex;
  justify-content: center;
  gap: 2rem;
  margin: 2.5rem 0;
  flex-wrap: wrap;
}

.about-team-member {
  text-align: center;
}

.about-team-member .img-placeholder {
  width: 140px;
  height: 140px;
  min-height: 0;
  border-radius: 50%;
  margin: 0 auto 0.75rem;
  font-size: 0.65rem;
}

.about-team-member span {
  display: block;
  font-family: var(--font-display);
  font-size: 1.05rem;
}

form {
  display: flex;
  gap: 1rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

label {
  display: flex;
  flex-direction: column;
  font-size: 0.85rem;
  gap: 0.25rem;
}

input {
  padding: 0.5rem;
  font-size: 1rem;
  min-width: 240px;
}

button {
  padding: 0.6rem 1.2rem;
  font-size: 1rem;
  cursor: pointer;
}

.flagged {
  background: #fdecea;
  border: 1px solid #f5c2c0;
  color: #611a15;
  padding: 1rem;
  border-radius: 6px;
  margin-bottom: 1.5rem;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

@media (max-width: 800px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 520px) {
  .grid {
    grid-template-columns: 1fr;
  }
}

.tile {
  background: #fff;
  border: 1px solid rgba(10, 22, 40, 0.08);
  box-shadow: 0 8px 28px rgba(10, 22, 40, 0.05);
  border-radius: 10px;
  padding: 1rem;
  text-align: center;
  transition: opacity 0.15s ease, box-shadow 0.15s ease;
}

.tile:hover {
  box-shadow: 0 10px 32px rgba(10, 22, 40, 0.08);
}

.tile.excluded {
  opacity: 0.4;
}

.tile-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.5rem;
}

.tile-header h2 {
  margin: 0;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tby-navy);
}

.tile-header .price {
  font-weight: 700;
  color: var(--tby-gold);
}

canvas {
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  max-width: 100%;
}

.toggle {
  display: flex;
  justify-content: center;
  gap: 1rem;
  font-size: 0.85rem;
  margin-top: 0.6rem;
}

/* --- Fixed vendor color swatches (box lid, UV print tumbler) --- */

.color-swatches {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.6rem;
  flex-wrap: wrap;
}

.color-swatch {
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--swatch-color);
  border: 1.5px solid rgba(10, 22, 40, 0.15);
  cursor: pointer;
  display: inline-block;
}

.color-swatch input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.color-swatch:has(input:checked) {
  outline: 2px solid var(--tby-gold);
  outline-offset: 2px;
}

.toggle label {
  flex-direction: row;
  align-items: center;
  gap: 0.3rem;
}

.include {
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  margin-top: 0.6rem;
}

.add-to-cart {
  display: block;
  width: 100%;
  margin-top: 0.6rem;
}

.prompt-details {
  text-align: left;
  margin-top: 0.6rem;
}

.prompt-details summary {
  cursor: pointer;
  font-size: 0.8rem;
  color: #777;
}

.prompt {
  white-space: pre-wrap;
  font-size: 0.7rem;
  color: #777;
  margin-top: 0.5rem;
  max-height: 6rem;
  overflow-y: auto;
}

/* --- Kids Party Box wizard --- */

.kpb-page {
  position: relative;
}

.kpb-step-nav {
  position: sticky;
  top: 74px;
  z-index: 15;
  background: var(--tby-cream);
  border-bottom: 1px solid rgba(10, 22, 40, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.9rem 1rem;
  flex-wrap: wrap;
}

.kpb-step-nav-item {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(10, 22, 40, 0.3);
}

.kpb-step-nav-item.is-complete {
  color: rgba(10, 22, 40, 0.55);
}

.kpb-step-nav-item.is-active {
  color: var(--tby-gold-dark);
}

.kpb-step-nav-arrow {
  color: rgba(10, 22, 40, 0.15);
  font-size: 0.8rem;
}

.kpb-step {
  max-width: 1040px;
  margin: 0 auto;
  padding: 3rem 1.5rem 4rem;
}

.kpb-step-inner-narrow {
  max-width: 620px;
  margin: 0 auto;
}

.kpb-step h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.9rem, 3.6vw, 2.75rem);
  line-height: 1.15;
  color: var(--tby-navy);
  letter-spacing: -0.3px;
  margin: 0 0 0.6rem;
}

.kpb-step-subhead {
  font-weight: 300;
  color: rgba(10, 22, 40, 0.55);
  font-size: 1rem;
  line-height: 1.6;
  margin: 0 0 2rem;
}

.kpb-section-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.2rem;
  color: var(--tby-navy);
  margin: 0 0 1rem;
}

.kpb-optional {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 300;
  font-style: italic;
  color: rgba(10, 22, 40, 0.4);
}

.kpb-required {
  color: var(--tby-gold);
  font-style: normal;
}

.kpb-step-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 2rem;
}

.kpb-step-actions-end {
  justify-content: flex-end;
}

.kpb-shake {
  animation: kpb-shake 0.4s ease;
}

@keyframes kpb-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}

/* Step 1 - Details */

.kpb-details-card {
  position: relative;
  background-color: var(--tby-navy);
  background-image: url("/constellation-navy.svg?v=13");
  background-repeat: repeat;
  background-position: center;
  /* Round-2: 900px -> 320px. At 900px this card (max ~620px wide) only
     ever showed a sliver of one tile, so too few of the field's 270 stars
     landed in the visible area and it read as "too subtle" - shrinking the
     tile packs several repeats into the card instead, same asset/opacity,
     just denser per visible inch. */
  background-size: 320px 320px;
  border-radius: 16px;
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  box-shadow: 0 12px 36px rgba(10, 22, 40, 0.18);
  overflow: hidden;
}

.kpb-details-card label {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(245, 240, 232, 0.5);
  display: block;
  margin-bottom: 0.5rem;
}

.kpb-details-card input {
  width: 100%;
  background: var(--tby-cream);
  border: 1px solid rgba(201, 168, 76, 0.25);
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
  font-size: 0.95rem;
  font-family: var(--font-body);
  color: var(--tby-navy);
}

.kpb-details-card input:focus {
  outline: none;
  border-color: var(--tby-gold);
}

.kpb-details-card input.kpb-field-invalid {
  border-color: var(--tby-gold-dark);
  box-shadow: 0 0 0 2px rgba(168, 135, 46, 0.35);
}

.kpb-details-subheading {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--tby-gold);
  padding-top: 1rem;
  margin-top: 0.25rem;
  border-top: 1px solid rgba(245, 240, 232, 0.12);
}

.kpb-details-subheading .kpb-optional {
  color: rgba(245, 240, 232, 0.4);
  font-size: 0.7rem;
}

/* Step 2 - Theme & Design */

.kpb-theme-layout {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 1.5rem;
  align-items: stretch;
  margin-bottom: 2.5rem;
}

@media (max-width: 800px) {
  .kpb-theme-layout {
    grid-template-columns: 1fr;
  }
}

.kpb-theme-grid {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-height: 560px;
  overflow-y: auto;
  padding-right: 0.25rem;
}

.kpb-theme-card {
  background: #FBF9F5;
  border: 1px solid rgba(10, 22, 40, 0.08);
  border-radius: 14px;
  padding: 1rem 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.kpb-theme-card:hover {
  box-shadow: 0 4px 14px rgba(10, 22, 40, 0.06);
}

.kpb-theme-card.is-selected {
  border-color: var(--tby-gold);
  background: rgba(201, 168, 76, 0.08);
  box-shadow: 0 6px 18px rgba(10, 22, 40, 0.1);
}

.kpb-theme-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: rgba(10, 22, 40, 0.04);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--tby-gold);
}

.kpb-theme-icon-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.kpb-theme-label {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1rem;
  color: var(--tby-navy);
}

.kpb-theme-sublabel {
  font-size: 0.7rem;
  color: rgba(10, 22, 40, 0.4);
  font-style: italic;
}

/* Preview panel: a light neutral cream card (not a fixed navy fill) so any
   theme's product photography - including future AI-generated custom
   themes, which have no fixed palette to key off of - sits on a consistent,
   uncluttered backdrop instead of clashing with a dark fill. Matches the
   cream card language already used for .kpb-theme-card/.kpb-personalize on
   this same step rather than inventing a new surface color. */
.kpb-preview-panel {
  background: #FBF9F5;
  border: 1px solid rgba(201, 168, 76, 0.3);
  border-radius: 20px;
  padding: 2.25rem;
  min-height: 460px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  box-shadow: 0 12px 32px rgba(10, 22, 40, 0.08);
}

.kpb-preview-placeholder {
  text-align: center;
  color: rgba(10, 22, 40, 0.55);
}

.kpb-preview-placeholder svg {
  color: var(--tby-gold);
  margin-bottom: 0.75rem;
}

.kpb-preview-placeholder p {
  font-style: italic;
  font-size: 0.85rem;
  margin: 0;
}

.kpb-preview-placeholder-sub {
  margin-top: 0.5rem !important;
  color: rgba(10, 22, 40, 0.35) !important;
}

.kpb-preview-name {
  text-align: center;
  font-family: var(--font-display);
  color: var(--tby-navy);
  font-size: 1.35rem;
  margin-bottom: 1.6rem;
}

/* Round-2: minmax 90px -> 170px. At 90px every theme's 4-5 items fit in
   one skinny row, leaving them centered as a small cluster inside a much
   taller stretched panel (the panel matches the theme-list column's
   height). Wider tiles wrap into 2 rows and read as a fuller, more
   dominant preview instead. */
.kpb-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 1.4rem;
}

.kpb-preview-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}

.kpb-preview-item img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(10, 22, 40, 0.08);
}

.kpb-preview-item span {
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(10, 22, 40, 0.45);
  text-align: center;
}

.kpb-personalize {
  background: #FBF9F5;
  border: 1px solid rgba(201, 168, 76, 0.3);
  border-radius: 14px;
  padding: 1.5rem 1.75rem;
  margin-bottom: 1rem;
}

.kpb-personalize .field {
  margin-bottom: 1rem;
}

.kpb-personalize .field:last-child {
  margin-bottom: 0;
}

.kpb-personalize label {
  display: block;
  font-weight: 600;
  font-size: 0.85rem;
  margin-bottom: 0.4rem;
  color: var(--tby-navy);
}

.kpb-personalize input,
.kpb-personalize textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;
  font-size: 0.9rem;
  font-family: var(--font-body);
  border: 1.5px solid rgba(10, 22, 40, 0.14);
  border-radius: 8px;
  background: #fff;
  resize: vertical;
}

.kpb-personalize input:focus,
.kpb-personalize textarea:focus {
  outline: none;
  border-color: var(--tby-gold);
}

.kpb-modal {
  position: fixed;
  inset: 0;
  background: rgba(10, 22, 40, 0.55);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.kpb-modal[hidden] {
  display: none;
}

.kpb-modal-inner {
  background-color: var(--tby-navy);
  background-image: url("/constellation-navy.svg?v=13");
  background-repeat: repeat;
  background-position: center;
  background-size: 900px 900px;
  border-radius: 20px;
  padding: 2.25rem;
  max-width: 480px;
  width: 100%;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
}

.kpb-modal-inner h2 {
  font-family: var(--font-display);
  color: var(--tby-cream);
  font-size: 1.5rem;
  font-weight: 500;
  margin: 0 0 0.4rem;
}

.kpb-modal-subhead {
  color: rgba(245, 240, 232, 0.5);
  font-size: 0.85rem;
  font-style: italic;
  margin: 0 0 1.25rem;
}

.kpb-modal-inner textarea {
  width: 100%;
  min-height: 90px;
  background: var(--tby-cream);
  border: 1px solid rgba(201, 168, 76, 0.25);
  border-radius: 8px;
  padding: 0.75rem 0.9rem;
  font-size: 0.9rem;
  font-family: var(--font-body);
  color: var(--tby-navy);
  resize: vertical;
  margin-bottom: 1.25rem;
}

.kpb-modal-actions {
  display: flex;
  gap: 0.75rem;
}

.kpb-modal-actions .btn {
  flex: 1;
}

/* .btn-outline is navy-on-transparent, invisible against this modal's own
   navy background - override to cream-on-transparent here only. */
.kpb-modal-actions .btn-outline {
  border-color: rgba(245, 240, 232, 0.4);
  color: var(--tby-cream);
}

.kpb-modal-actions .btn-outline:hover {
  background: rgba(245, 240, 232, 0.1);
  color: var(--tby-cream);
}

/* Step 3 - Products */

.kpb-guest-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.kpb-guest-row label {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--tby-navy);
  flex-shrink: 0;
}

.kpb-guest-row input[type="range"] {
  flex: 1;
}

.kpb-guest-count-display {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--tby-navy);
  min-width: 2ch;
  text-align: right;
}

.kpb-guest-note {
  font-size: 0.8rem;
  color: rgba(10, 22, 40, 0.45);
  margin: 0 0 2rem;
}

.kpb-guest-note a {
  color: var(--tby-gold-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Round-2: tier cards now live stacked in the narrow left column of
   .kpb-build-layout (not a standalone 3-across row), so this is a simple
   vertical stack at every width rather than a grid that collapses to 1fr
   under a breakpoint. */
.kpb-tier-grid {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  margin-bottom: 1.5rem;
}

.kpb-tier-card {
  background: #FDFCFA;
  border: 1px solid rgba(10, 22, 40, 0.08);
  border-radius: 14px;
  padding: 1.5rem;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.kpb-tier-card:hover {
  transform: translateY(-2px);
}

.kpb-tier-card.is-selected {
  border-color: var(--tby-gold);
  box-shadow: 0 10px 28px rgba(10, 22, 40, 0.14);
}

.kpb-tier-label {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.15rem;
  color: var(--tby-navy);
}

.kpb-tier-price {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.6rem;
  color: var(--tby-gold-dark);
  margin: 0.2rem 0 0.9rem;
}

.kpb-tier-count {
  font-size: 0.78rem;
  font-style: italic;
  color: rgba(10, 22, 40, 0.45);
}

/* Step 3 restructure (round 2): same left-narrow/right-wide split-screen
   pattern established on Step 2 (.kpb-theme-layout) - left column holds
   the guest slider, stacked tier cards, and a footer (total + actions)
   pinned to the bottom of the column via margin-top:auto; right column is
   just the product grid, now with room to run its cards bigger. */
.kpb-build-layout {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 1.5rem;
  align-items: start;
}

@media (max-width: 800px) {
  .kpb-build-layout {
    grid-template-columns: 1fr;
  }
}

/* Sticky, not grid-stretched: with ~25+ product cards on the right,
   stretching this column to match that height (align-items: stretch) put
   the total/checkout button at the very bottom of the whole page - unusable,
   you'd have to scroll past the entire catalog to check out. Sticky keeps
   this column reachable while the product grid scrolls past beside it. top
   offset clears the sticky site header (74px) + sticky step nav (~49px).
   max-height + the .kpb-build-left-scroll wrapper below handle the other
   failure mode: on short viewports the guest slider + 3 tier cards can
   themselves be taller than the space available under the sticky offset,
   which would clip the footer (total/buttons) off the bottom with no way
   to reach it. Making only that upper part internally scrollable - while
   the footer stays a normal flex child below it, always fully visible -
   is what actually delivers "total + button anchored at the bottom of the
   column" without an unreachable checkout button on smaller screens. */
.kpb-build-left {
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 130px;
  max-height: calc(100vh - 150px);
}

@media (max-width: 800px) {
  .kpb-build-left {
    position: static;
    max-height: none;
  }
}

.kpb-build-left-scroll {
  overflow-y: auto;
  min-height: 0;
}

.kpb-build-left-footer {
  flex-shrink: 0;
  padding-top: 1.5rem;
}

.kpb-build-right {
  min-width: 0;
}

.kpb-product-grid-note {
  font-size: 0.8rem;
  color: rgba(10, 22, 40, 0.45);
  margin: -0.4rem 0 1.1rem;
}

/* Step 3 - unified product grid: every tier item + add-on, themed photo
   where pricing.js has art for that slot, a line icon otherwise (see
   wizard.js PRODUCT_ICON_PATHS). .is-included = full color (in the box at
   the current tier, or a checked/qty>0 add-on); .is-locked = greyed out. */
/* Round-2: minmax 140px -> 190px, gap 0.85rem -> 1.1rem - now that the
   grid lives in .kpb-build-right (roughly 2/3 of the step width, not the
   full 1040px step) rather than shrinking cards to fit, this makes each
   card bigger/more prominent as asked, at the cost of more rows. */
.kpb-product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 1.1rem;
}

.kpb-product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1.5px solid rgba(10, 22, 40, 0.08);
  border-radius: 12px;
  padding: 1rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.kpb-product-card-addon {
  cursor: pointer;
}

.kpb-product-checkbox {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  margin: 0;
  z-index: 1;
}

.kpb-product-media {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(10, 22, 40, 0.03);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.6rem;
}

.kpb-product-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.kpb-product-icon-svg {
  width: 40%;
  height: 40%;
  color: var(--tby-gold);
}

.kpb-product-name {
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--tby-navy);
  line-height: 1.3;
}

.kpb-product-status {
  font-size: 0.76rem;
  color: rgba(10, 22, 40, 0.45);
  margin-top: 0.3rem;
}

.kpb-product-card.is-included {
  border-color: var(--tby-gold);
  box-shadow: 0 4px 16px rgba(10, 22, 40, 0.08);
}

.kpb-product-card.is-locked {
  opacity: 0.5;
}

.kpb-product-card.is-locked .kpb-product-media {
  filter: grayscale(0.7);
}

.kpb-product-card-addon.is-locked:hover {
  opacity: 0.75;
}

.kpb-product-card-tshirt {
  grid-column: span 2;
}

@media (max-width: 480px) {
  .kpb-product-card-tshirt {
    grid-column: 1 / -1;
  }
}

.kpb-tshirt-stepper {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.6rem;
}

.kpb-tshirt-step-btn {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid rgba(10, 22, 40, 0.15);
  background: #fff;
  color: var(--tby-navy);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.kpb-tshirt-step-btn:hover {
  border-color: var(--tby-gold);
}

.kpb-tshirt-qty {
  font-weight: 600;
  color: var(--tby-navy);
  min-width: 1.2rem;
  text-align: center;
}

.kpb-tshirt-texts {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

.kpb-tshirt-text-input {
  width: 100%;
  padding: 0.45rem 0.6rem;
  font-size: 0.8rem;
  font-family: var(--font-body);
  border: 1.5px solid rgba(10, 22, 40, 0.12);
  border-radius: 6px;
  background: var(--tby-cream);
  color: var(--tby-navy);
}

.kpb-tshirt-text-input:focus {
  outline: none;
  border-color: var(--tby-gold);
}

.kpb-summary-bar {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-top: 2px solid var(--tby-navy);
  padding-top: 1rem;
  margin-bottom: 0.5rem;
  font-family: var(--font-display);
}

.kpb-summary-bar span:first-child {
  font-size: 0.95rem;
  color: rgba(10, 22, 40, 0.6);
}

.kpb-summary-bar span:last-child {
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--tby-navy);
}

/* Step 4 - Review */

.kpb-review-card {
  background: #FDFCFA;
  border: 1px solid rgba(10, 22, 40, 0.07);
  border-radius: 16px;
  padding: 1.75rem;
  box-shadow: 0 4px 24px rgba(10, 22, 40, 0.06);
}

.kpb-review-row-header {
  padding-bottom: 1.1rem;
  border-bottom: 1px solid rgba(10, 22, 40, 0.07);
  margin-bottom: 1.1rem;
}

.kpb-review-tier {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.2rem;
  color: var(--tby-navy);
}

.kpb-review-theme {
  font-size: 0.75rem;
  color: rgba(10, 22, 40, 0.4);
  font-style: italic;
  margin-top: 0.2rem;
}

.kpb-review-personalize {
  font-size: 0.75rem;
  color: rgba(10, 22, 40, 0.45);
  margin-top: 0.2rem;
}

.kpb-review-lines {
  margin-bottom: 1.1rem;
}

.kpb-review-line {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--tby-navy);
  padding: 0.3rem 0;
}

.kpb-review-row-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-top: 1rem;
  border-top: 1px solid rgba(10, 22, 40, 0.09);
  font-family: var(--font-display);
}

.kpb-review-row-total span:first-child {
  font-size: 1.05rem;
  color: var(--tby-navy);
}

.kpb-review-row-total span:last-child {
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--tby-navy);
}

/* ===== Start Designing landing page ===== */

.sd-back-home {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: rgba(10, 22, 40, 0.45);
  text-decoration: none;
}

.sd-back-home:hover {
  color: var(--tby-navy);
}

.sd-page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 1.5rem 4rem;
}

.sd-intro {
  text-align: center;
  padding: 4rem 1.5rem 0.5rem;
  max-width: 560px;
  margin: 0 auto;
}

.sd-rule {
  width: 36px;
  height: 1px;
  background: rgba(201, 168, 76, 0.7);
  margin: 0 auto 1.25rem;
}

.sd-intro h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.9rem, 3.6vw, 2.75rem);
  line-height: 1.15;
  color: var(--tby-navy);
  letter-spacing: -0.3px;
  margin: 0 0 0.9rem;
}

.sd-subhead {
  font-weight: 300;
  color: rgba(10, 22, 40, 0.5);
  font-size: 0.9rem;
  line-height: 1.6;
  margin: 0;
}

.sd-panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 480px;
  margin-top: 3rem;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(10, 22, 40, 0.1);
}

@media (max-width: 800px) {
  .sd-panels {
    grid-template-columns: 1fr;
  }
}

.sd-panel {
  padding: 3.5rem 3rem 4rem;
}

.sd-panel-b2c {
  background: var(--tby-cream);
}

.sd-panel-b2b {
  background-color: var(--tby-navy);
  background-image: url("/constellation-navy.svg?v=13");
  background-repeat: repeat;
  background-position: center;
  background-size: 900px 900px;
  position: relative;
}

.sd-eyebrow {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(10, 22, 40, 0.4);
  margin-bottom: 0.6rem;
  position: relative;
}

.sd-panel-b2b .sd-eyebrow {
  color: rgba(201, 168, 76, 0.7);
}

.sd-panel h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.75rem;
  color: var(--tby-navy);
  margin: 0 0 2rem;
  position: relative;
}

.sd-panel-b2b h2 {
  color: var(--tby-cream);
}

.sd-cards {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  position: relative;
  z-index: 1;
}

.sd-card {
  background: #FBF9F5;
  border: 1px solid rgba(201, 168, 76, 0.4);
  border-radius: 14px;
  box-shadow: 0 2px 12px rgba(10, 22, 40, 0.05);
  padding: 1.6rem 1.75rem;
  display: flex;
  align-items: center;
  gap: 1.35rem;
  text-decoration: none;
  color: inherit;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.sd-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 32px rgba(10, 22, 40, 0.1);
}

.sd-panel-b2b .sd-card {
  background: rgba(245, 240, 232, 0.04);
  border-color: rgba(201, 168, 76, 0.3);
}

.sd-card-icon {
  flex-shrink: 0;
  color: var(--tby-teal);
}

.sd-card-copy {
  flex: 1;
}

.sd-card-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.15rem;
  color: var(--tby-navy);
  margin-bottom: 0.2rem;
}

.sd-panel-b2b .sd-card-name {
  color: var(--tby-cream);
}

.sd-card-desc {
  font-size: 0.72rem;
  color: rgba(10, 22, 40, 0.5);
  line-height: 1.5;
}

.sd-panel-b2b .sd-card-desc {
  color: rgba(245, 240, 232, 0.5);
}

.sd-card-arrow {
  flex-shrink: 0;
  color: var(--tby-navy);
  transition: transform 0.15s ease;
}

.sd-panel-b2b .sd-card-arrow {
  color: var(--tby-cream);
}

.sd-card:hover .sd-card-arrow {
  transform: translateX(4px);
}

.sd-more-note {
  padding: 0.4rem 0.25rem 0;
  margin: 0;
  font-size: 0.72rem;
  font-style: italic;
  color: rgba(10, 22, 40, 0.35);
}

.sd-panel-b2b .sd-more-note {
  color: rgba(245, 240, 232, 0.35);
}
