/* Petra styles — extracted from index.html (block 2). Versioned + 1-year immutable cache. Bump v1->v2 on any change. */

    /* === INVISIBLE MODERN FOUNDATIONS === */
    
    /* Smooth, organic base transitions - never jarring */
    * { 
      box-sizing: border-box;
      -webkit-tap-highlight-color: transparent;
    }
    
    /* Organic easing - feels like natural movement */
    :root {
      /* ═══ PETRA COLOR TOKENS (Pantone audit) — the canonical palette and single
         source of truth. Change a value here to re-skin everywhere it is referenced.
         Surfaces are migrated onto these incrementally; usages carry a literal
         fallback so a missed stylesheet load still renders correctly. ═══ */
      --petra-cream:       #F4EFE7;  /* dominant canvas */
      --petra-paper-light: #FAF8F3;  /* cards, trays */
      --petra-paper-warm:  #FBF4E3;  /* stationery */
      --petra-linen:       #EDE5D6;  /* desk surfaces */
      --petra-ink:         #2A1810;  /* body text */
      --petra-caption:     #6d5a3c;  /* AA-safe muted captions / micro-labels */
      --petra-cta-1:       #FF6545;  /* action gradient — flame top sheen */
      --petra-cta-2:       #E85D3B;  /* action gradient — terracotta mid */
      --petra-cta-3:       #C04525;  /* action gradient — sienna base */
      --petra-maroon:      #5A1A22;  /* nav / wax heritage */
      --petra-gold:        #C9A961;  /* brass / gilt */
      --petra-cognac:      #B8825A;  /* leather */
      --petra-remembrance: #7B838C;  /* semantic — mourning slate */

      --ease-gentle: cubic-bezier(0.4, 0, 0.2, 1);
      --ease-settle: cubic-bezier(0.22, 1, 0.36, 1);
      --ease-soft: cubic-bezier(0.25, 0.1, 0.25, 1);
      --duration-quick: 120ms;
      --duration-normal: 200ms;
      --duration-slow: 350ms;
    }
    
    body { 
      font-family: 'DM Sans', system-ui, sans-serif; 
      margin: 0;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    /* Focus states that feel like illumination, not highlight */
    :focus-visible {
      outline: none;
      box-shadow: 0 0 0 2px rgba(196, 164, 132, 0.4);
      border-radius: inherit;
    }
    
    /* Buttons - organic feedback */
    button {
      cursor: pointer;
      border: none;
      background: none;
    }
    
    /* Smooth scrolling that doesn't feel digital */
    .smooth-scroll {
      scroll-behavior: smooth;
      -webkit-overflow-scrolling: touch;
    }
    
    /* Loading states - calm, not anxious */
    .loading {
      opacity: 0.7;
      pointer-events: none;
    }
    
    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }
    
    /* === END INVISIBLE FOUNDATIONS === */
    
    /* ═══════ LEGEND-TIER: SPRING PHYSICS CSS VARIABLES ═══════ */
    :root {
      /* Spring presets - mass × stiffness × damping triads */
      --spring-postcard-mass: 1.5;
      --spring-postcard-stiffness: 180;
      --spring-postcard-damping: 14;
      --spring-album-mass: 3.2;
      --spring-album-stiffness: 100;
      --spring-album-damping: 12;
      --spring-album-gravity: 3.0;
      
      /* Ink-Life simulation */
      --ink-wetness: 1.0;
      --ink-bleed-radius: 1.2;
      --ink-dry-duration: 2s;
      --ink-settle-sharpness: 0;
      
      /* Typography - refined tracking for small sizes */
      --tracking-11px: 0.025em;
      --tracking-10px: 0.035em;
      --tracking-9px: 0.045em;
      --tracking-8px: 0.05em;
    }
    
    /* ═══════ LEGEND-TIER: CORNER-CURL HINT ═══════ */
    /* ═══════ HOME FLIP CARD (hfc- prefix to avoid conflicts) ═══════ */
    .hfc-scene {
      perspective: 1200px;
      width: 100%;
    }
    .hfc-card {
      width: 100%;
      aspect-ratio: 3 / 2;
      position: relative;
      cursor: pointer;
      transform-style: preserve-3d;
    }
    .hfc-card.flipped {
      transform: rotateY(180deg);
    }
    .hfc-face {
      position: absolute;
      top: 0; left: 0; width: 100%; height: 100%;
      backface-visibility: hidden;
      -webkit-backface-visibility: hidden;
      border-radius: 5px;
      overflow: hidden;
      /* Card stock thickness — keepsake depth */
      box-shadow:
        0 1px 0 rgba(195,175,145,0.45),
        0 2px 0 rgba(175,155,125,0.3),
        0 3px 0 rgba(155,138,110,0.18),
        0 5px 10px rgba(80,55,30,0.15),
        0 10px 24px rgba(60,40,20,0.1),
        0 20px 40px rgba(40,25,10,0.06),
        inset 0 1px 0 rgba(255,252,242,0.5),
        inset 0 -1px 0 rgba(140,115,80,0.1);
    }
    .hfc-front {
      background: #5a7080;
      z-index: 2;
    }
    .hfc-back {
      background: linear-gradient(180deg, #faf8f3, #f5f0e8 40%, #efe8dc);
      transform: rotateY(180deg);
      z-index: 1;
    }
    .hfc-media-btn {
      width: 32px; height: 32px;
      border-radius: 50%; border: none; cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      background: linear-gradient(145deg, #c4a87a 0%, #a8905e 30%, #8b7548 60%, #7a6840 100%);
      box-shadow: 0 3px 8px rgba(90,70,40,0.35), 0 1px 2px rgba(0,0,0,0.2),
        inset 0 1px 0 rgba(255,230,180,0.4), inset 0 -1px 0 rgba(50,35,15,0.3);
      transition: transform 0.2s;
    }
    .hfc-media-btn:hover { transform: scale(1.08); }
    .hfc-media-btn:active { transform: scale(0.95); }
    /* ═══════ STAMP/TICKET PLACEMENT ANIMATIONS ═══════ */
    @keyframes stampPress {
      0%   { transform: scale(1.3) rotate(-4deg); opacity: 0.5; }
      35%  { transform: scale(0.92) rotate(1deg); opacity: 1; }
      55%  { transform: scale(1.06) rotate(-0.5deg); }
      75%  { transform: scale(0.98) rotate(0.2deg); }
      100% { transform: scale(1) rotate(0deg); }
    }
    @keyframes stampGlow {
      0%   { box-shadow: 0 0 0 0 rgba(184,155,74,0.4); }
      50%  { box-shadow: 0 0 12px 4px rgba(184,155,74,0.15); }
      100% { box-shadow: 0 0 0 0 rgba(184,155,74,0); }
    }
    @keyframes ticketSlideIn {
      0%   { transform: translate(-50%,-50%) rotate(-8deg) scale(1.2); opacity: 0.4; }
      40%  { transform: translate(-50%,-50%) rotate(-1deg) scale(0.95); opacity: 1; }
      60%  { transform: translate(-50%,-50%) rotate(-4deg) scale(1.03); }
      100% { transform: translate(-50%,-50%) rotate(-3deg) scale(1); }
    }
    @keyframes btnSelectPulse {
      0%   { transform: scale(1); }
      25%  { transform: scale(0.9); }
      50%  { transform: scale(1.08); }
      75%  { transform: scale(0.97); }
      100% { transform: scale(1); }
    }
    .stamp-placing {
      animation: stampPress 0.45s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    .stamp-glow {
      animation: stampGlow 0.6s ease-out forwards;
    }
    .ticket-placing {
      animation: ticketSlideIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    .stamp-btn-selected-pulse {
      animation: btnSelectPulse 0.35s cubic-bezier(0.22, 1, 0.36, 1);
    }

    /* ═══════ LUXURY ADD-ON TICKET BUTTONS ═══════ */
    /* ═══ ADDON BUTTONS — Ralph Lauren Equestrian Heritage ═══ */
    /* Saddle-stitched leather tabs with antique brass hardware */
    /* ═══ KEEPSAKE ADDON BUTTONS — Debossed foil label on aged parchment ═══ */
    .addon-ticket-btn {
      position: relative;
      background: none; border: none; cursor: pointer; padding: 0;
      transition: transform 0.2s cubic-bezier(0.22,1,0.36,1), opacity 0.2s;
      flex: 1;
    }
    .addon-ticket-btn:hover { transform: translateY(-1px); }
    .addon-ticket-btn:active { transform: translateY(0.5px); }
    .addon-ticket-inner {
      display: flex; align-items: center; justify-content: center; gap: 6px;
      padding: 10px 0;
      /* Warm aged cotton — like the inside of a keepsake box lid */
      background: linear-gradient(178deg, #f8f4ee 0%, #f0ebe2 60%, #e8e2d6 100%);
      color: #6b5c48;
      font-family: 'DM Sans', sans-serif;
      font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
      border-radius: 6px;
      position: relative;
      /* Fine shadow like a card sitting on paper */
      box-shadow:
        0 1px 3px rgba(107,92,72,0.12),
        0 0 0 1px rgba(107,92,72,0.08),
        inset 0 1px 0 rgba(255,255,255,0.7);
    }
    .addon-ticket-inner::after {
      content: '';
      position: absolute; inset: 0; border-radius: 6px;
      /* Subtle paper texture grain */
      background: linear-gradient(180deg, transparent 0%, rgba(107,92,72,0.02) 100%);
      pointer-events: none;
    }
    /* Active state — pressed into the page, like a debossed impression */
    .addon-ticket-btn.active .addon-ticket-inner {
      background: linear-gradient(178deg, #2a2420 0%, #1e1a16 100%);
      color: #d4c5a8;
      box-shadow:
        0 1px 2px rgba(0,0,0,0.15),
        inset 0 1px 4px rgba(0,0,0,0.2),
        inset 0 0 0 1px rgba(255,255,255,0.04);
    }
    .addon-ticket-btn.active .addon-ticket-inner .addon-brass-icon svg {
      stroke: #c9a94e;
    }
    .addon-ticket-btn.voice-note-ready .addon-ticket-inner {
      background: linear-gradient(178deg, #3a241d 0%, #261814 100%);
      color: #ead4a8;
      box-shadow:
        0 1px 2px rgba(0,0,0,0.16),
        inset 0 1px 4px rgba(0,0,0,0.22),
        inset 0 0 0 1px rgba(234,212,168,0.08);
    }
    .addon-ticket-btn.voice-note-ready .addon-brass-icon svg {
      stroke: #d8b768;
    }
    .voice-note-ready-badge {
      display: none;
      width: 6px;
      height: 6px;
      border-radius: 999px;
      background: #2A9D8F;
      box-shadow: 0 0 0 2px rgba(234,212,168,0.14);
    }
    .addon-ticket-btn.voice-note-ready .voice-note-ready-badge {
      display: inline-flex;
    }
    /* Icon — thin engraved line, like a debossed detail on fine stationery */
    .addon-brass-icon {
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
    }

    /* 2026-06-08 — Dieter Rams redesign (option 2, "Solid disc"): the ornate
       pressed-wax seal becomes a clean, flat terracotta button. Same warm red,
       none of the ceremony — one functional colour, a clear "press me" disc. */
    .pc-voice-seal {
      position: relative;
      border: none;
      border-radius: 50%;
      cursor: pointer;
      background: #b5432a;
      color: #fbf3e9;
      box-shadow: 0 1px 3px rgba(120, 45, 25, 0.30), 0 3px 9px rgba(120, 45, 25, 0.14);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      transition: transform 0.16s cubic-bezier(0.22,1,0.36,1), box-shadow 0.16s cubic-bezier(0.22,1,0.36,1), background 0.16s ease;
      isolation: isolate;
    }
    .pc-voice-seal::before { content: none; }
    .pc-voice-seal::after { content: none; }
    .pc-voice-seal:hover { transform: translateY(-1px); background: #bf492f; }
    .pc-voice-seal:active { transform: translateY(0) scale(0.95); }
    .pc-voice-seal[data-playing="true"] {
      background: #9f3a23;
      box-shadow: 0 1px 3px rgba(120, 45, 25, 0.30), 0 0 0 4px rgba(181, 67, 42, 0.16);
    }
    .pc-voice-seal-front { width: 38px; height: 38px; }
    .pc-voice-seal-back { width: 28px; height: 28px; flex-shrink: 0; }
    .pc-voice-seal-front .pc-voice-glyph { width: 17px; height: 17px; }
    .pc-voice-seal-back .pc-voice-glyph { width: 13px; height: 13px; }
    .pc-voice-glyph {
      display: flex;
      align-items: center;
      justify-content: center;
      color: currentColor;
    }

    .hfc-hint {
      text-align: center; margin-top: 8px;
      opacity: 0; animation: hfcFadeIn 0.6s ease 1.2s forwards;
    }
    @keyframes hfcFadeIn {
      from { opacity: 0; transform: translateY(6px); }
      to { opacity: 1; transform: translateY(0); }
    }
    @keyframes hfcRotate {
      0%, 100% { transform: rotateY(0deg); }
      50% { transform: rotateY(180deg); }
    }

    @keyframes corner-curl-hint {
      0% { 
        background-size: 0 0;
        box-shadow: none;
      }
      15% {
        background-size: 42px 42px;
        box-shadow: -3px -3px 6px rgba(0,0,0,0.08);
      }
      40% {
        background-size: 48px 48px;
        box-shadow: -4px -4px 10px rgba(0,0,0,0.12);
      }
      65% {
        background-size: 42px 42px;
        box-shadow: -3px -3px 6px rgba(0,0,0,0.08);
      }
      85% {
        background-size: 20px 20px;
        box-shadow: -1px -1px 3px rgba(0,0,0,0.05);
      }
      100% {
        background-size: 0 0;
        box-shadow: none;
      }
    }
    
    .corner-curl-hint::after {
      content: '';
      position: absolute;
      bottom: 0;
      right: 0;
      width: 60px;
      height: 60px;
      background: linear-gradient(225deg, 
        rgba(244,239,231,0.95) 0%,
        rgba(244,239,231,0.9) 35%,
        rgba(220,210,195,0.7) 50%,
        transparent 50.5%
      );
      background-position: bottom right;
      background-repeat: no-repeat;
      background-size: 0 0;
      border-radius: 0 0 12px 0;
      animation: corner-curl-hint 2.8s var(--ease-settle) 1.5s 2 forwards;
      pointer-events: none;
      z-index: 15;
    }
    
    /* ═══════ LEGEND-TIER: REFINED INK-LIFE EFFECT ═══════ */
    @keyframes ink-life-bleed {
      0% {
        filter: url(#ink-life-wet) brightness(1.35) contrast(0.75) saturate(0.6);
        opacity: 0.6;
        transform: scale(1.004);
      }
      12% {
        filter: url(#ink-life-settling) brightness(1.25) contrast(0.82) saturate(0.7);
        opacity: 0.75;
        transform: scale(1.003);
      }
      30% {
        filter: url(#ink-life-settling) brightness(1.15) contrast(0.88) saturate(0.8);
        opacity: 0.85;
        transform: scale(1.002);
      }
      55% {
        filter: brightness(1.06) contrast(0.94) saturate(0.92);
        opacity: 0.93;
        transform: scale(1.001);
      }
      80% {
        filter: brightness(1.02) contrast(0.98) saturate(0.97);
        opacity: 0.98;
        transform: scale(1.0003);
      }
      100% {
        filter: brightness(1) contrast(1.05) saturate(1);
        opacity: 1;
        transform: scale(1);
      }
    }
    
    .ink-life-active {
      animation: ink-life-bleed var(--ink-dry-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    
    /* Wet ink shimmer - capillary action simulation */
    @keyframes ink-capillary {
      0%, 100% { filter: brightness(1.3) contrast(0.78); transform: scale(1.003); }
      15% { filter: brightness(1.22) contrast(0.82); transform: scale(1.0025); }
      35% { filter: brightness(1.28) contrast(0.79); transform: scale(1.0028); }
      50% { filter: brightness(1.18) contrast(0.85); transform: scale(1.002); }
      70% { filter: brightness(1.24) contrast(0.81); transform: scale(1.0022); }
      85% { filter: brightness(1.15) contrast(0.87); transform: scale(1.0015); }
    }
    
    .ink-wet-shimmer {
      animation: ink-capillary 0.6s ease-in-out 3;
    }
    
    /* ═══════ LEGEND-TIER: HUMAN IRREGULARITY (handwritten fonts) ═══════ */
    .human-irregular {
      display: inline-block;
    }
    .human-irregular > span {
      display: inline-block;
      transition: none;
    }
    
    /* ═══════ LEGEND-TIER: TYPOGRAPHY LEGIBILITY ═══════ */
    /* Optimized tracking for small Cormorant Garamond */
    .font-serif {
      /* Base: already declared, just enhance small sizes */
    }
    
    /* 11px and below: widen tracking for legibility */
    .text-\[10px\], .text-\[9px\], .text-\[8px\] {
      letter-spacing: var(--tracking-10px) !important;
    }
    .text-\[11px\] {
      letter-spacing: var(--tracking-11px) !important;
    }
    
    /* Small serif text gets optical compensation */
    .font-serif[style*="font-size: 10"],
    .font-serif[style*="font-size: 11"],
    .font-serif[style*="font-size: 9"] {
      letter-spacing: 0.03em !important;
      -webkit-font-smoothing: antialiased;
    }
    
    .font-serif { font-family: 'Cormorant Garamond', Georgia, serif !important; }
    .font-hand { font-family: 'Homemade Apple', cursive !important; }
    .font-lubalin { font-family: 'Outfit', sans-serif !important; }
    .font-shaded {
      font-family: 'Playfair Display', Georgia, serif !important;
      font-weight: 700;
      letter-spacing: 0.08em;
      background: repeating-linear-gradient(
        0deg,
        #C75540 0px,
        #C75540 2px,
        transparent 2px,
        transparent 4px
      );
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      position: relative;
    }
    
    @keyframes fadeUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
    @keyframes pulse-slow { 0%, 100% { opacity: 0.4; } 50% { opacity: 0.6; } }
    /* Used by the voice-recording timer's "about to cut" warning state
       (last ~2 seconds before the 60s cap). A subtle scale pulse draws
       the eye without being loud — the user notices, no panic. */
    @keyframes voice-cap-pulse {
      0%, 100% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.06); opacity: 0.78; }
    }
    /* Two-stage warning when a voice recording approaches its 60s cap.
       Class-based so we can toggle without nuking the timer's original
       inline color. Used by both Postcard and Groupsake recorders. */
    .voice-timer-warn { color: #B86C28 !important; transition: color 0.4s ease; }
    .voice-timer-cap  { color: #9B1F1F !important; animation: voice-cap-pulse 0.8s ease-in-out infinite; }
    /* Brass-dot pulse used by the email-verification "waiting" indicator
       — soft halo grows + fades, matching the keepsake palette without
       drawing attention away from the user's main task (open inbox). */
    @keyframes email-verify-pulse {
      0%   { box-shadow: 0 0 0 0 rgba(184,136,56,0.55); }
      70%  { box-shadow: 0 0 0 10px rgba(184,136,56,0); }
      100% { box-shadow: 0 0 0 0 rgba(184,136,56,0); }
    }
    /* Banner sits sticky at the top of #home-screen for any signed-in
       user whose email isn't verified yet. After 5 minutes of being
       ignored, the .email-verify-pulsing class is added — the whole bar
       gets a slow glow and the envelope icon wiggles softly. Calibrated
       to be noticeable but not nagging; matches the keepsake palette. */
    @keyframes email-verify-banner-pulse {
      0%, 100% { box-shadow: 0 2px 8px rgba(40,28,18,0.06); }
      50%      { box-shadow: 0 2px 18px rgba(154,98,56,0.32); }
    }
    @keyframes email-verify-banner-wiggle {
      0%, 100% { transform: rotate(0deg); }
      20%      { transform: rotate(-7deg); }
      40%      { transform: rotate(5deg); }
      60%      { transform: rotate(-3deg); }
      80%      { transform: rotate(1deg); }
    }
    @keyframes email-verify-banner-in {
      0%   { opacity: 0; transform: translateY(-6px); }
      100% { opacity: 1; transform: translateY(0); }
    }
    #email-verify-banner { animation: email-verify-banner-in 0.36s ease-out both; }
    /* Specificity bumped (#…&.…) so the pulse animation overrides the
       one-shot entrance animation declared on #email-verify-banner. */
    #email-verify-banner.email-verify-pulsing { animation: email-verify-banner-pulse 2.6s ease-in-out infinite; }
    #email-verify-banner.email-verify-pulsing .evb-icon { animation: email-verify-banner-wiggle 2.6s ease-in-out infinite; transform-origin: center; }

    /* ═══════════════════════════════════════════════════════════════
       Add-phone banner — sticky at top of home for users without a
       phone on file. Same architecture as email-verify-banner but
       Nile-blue accent so the two banners don't conflict visually
       if both ever appear in the same session. ════════════════════ */
    #add-phone-banner { animation: email-verify-banner-in 0.36s ease-out both; }

    /* ═══════════════════════════════════════════════════════════════
       iOS Safari smoothness patch — 2026-05-23 (Tier 0)
       Three coordinated CSS fixes addressing reported iPhone bugs:
       (a) "send button sometimes doesn't fire" → 300ms tap delay on
           buttons without an explicit touch-action opt-out
       (b) "scrolling not smooth" → 50+ backdrop-filter:blur(8-12px)
           overlays re-blurring on every animation frame on iOS GPU
       (c) "home views jumbled" → iOS Safari hit-tests fail on tiles
           mid-transform-transition unless they're composited
       Android Chrome and Samsung Browser are NOT affected by (b) —
       it sits inside an @supports(-webkit-touch-callout: none) block,
       a CSS property that only exists on iOS Safari. Android sees
       the original blur values. (a) and (c) are universal best
       practice that quietly benefit Android too. ═══════════════ */

    /* (a) Universal — disable double-tap-zoom on buttons. Cures the
           300ms wait between tap and action that iOS Safari injects
           when it's deciding whether you mean to double-tap-zoom.
           Buttons never need that gesture, so opt out everywhere. */
    button { touch-action: manipulation; }

    /* (b) iOS-only — cap backdrop-filter blur at 4px. iOS Safari
           recomputes the blur every animation frame on the GPU; with
           50+ blurred modal/sheet overlays in the app, scroll
           dropped to 20-30fps on iPhone XS-class hardware. The cap
           uses an attribute selector that catches every inline
           backdrop-filter declaration in the document. */
    @supports (-webkit-touch-callout: none) {
      *[style*="backdrop-filter"] {
        backdrop-filter: blur(4px) !important;
        -webkit-backdrop-filter: blur(4px) !important;
      }
    }

    /* (c) GPU-promote home-screen tiles so iOS Safari can hit-test
           them while their inner animations play. Without this, a
           tap that lands mid-animation can be missed entirely. */
    .journal-card-surface { will-change: transform; }
    @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
    
    /* ═══════ PETRA POST OFFICE — sorting case animations ═══════ */
    /* Default: cabinet sits quietly with a slight drop shadow.
       When unread mail arrives, the wax-sealed letter pulses gently,
       like ink still warm. The cabinet itself nudges on hover. */
    @keyframes po-seal-pulse {
      0%, 100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(196,72,48,0)); }
      50%      { transform: scale(1.10); filter: drop-shadow(0 0 3px rgba(196,72,48,0.55)); }
    }
    @keyframes po-letter-settle {
      0%   { transform: rotate(-3deg) translateY(-1.2px); }
      50%  { transform: rotate(-3deg) translateY(0.4px); }
      100% { transform: rotate(-3deg) translateY(-1.2px); }
    }
    @keyframes po-cabinet-nudge {
      0%, 100% { transform: rotate(0deg); }
      30% { transform: rotate(-0.6deg); }
      60% { transform: rotate(0.4deg); }
    }

    /* The wax seal lives inside .po-seal-group; only animates when the
       inbox is "unread" (class set by JS when there's incoming mail). */
    .petra-postoffice-btn .po-seal-group { transform-origin: 31.5px 20.5px; }
    .petra-postoffice-btn.has-unread .po-seal-group {
      animation: po-seal-pulse 2.4s ease-in-out infinite;
    }
    .petra-postoffice-btn.has-unread .po-letter {
      animation: po-letter-settle 4s ease-in-out infinite;
      transform-origin: 31.5px 19.7px;
    }

    .petra-postoffice-btn svg {
      filter: drop-shadow(0 2px 4px rgba(140,110,60,0.28));
      transform-origin: center bottom;
    }
    .petra-postoffice-btn:hover svg {
      animation: po-cabinet-nudge 0.6s ease-in-out;
    }

    /* ─── Petra cabinet-card portrait frame (home avatar) ───
       A small Victorian-cabinet-portrait-style frame: warm gilt-cream
       outer band, a recessed cream mat, subtle gold pinstripe inset,
       and four tiny brass photo corners (the kind that held photos
       to scrapbook pages). Hand-placed at -1.5°. */
    .petra-portrait-frame-btn { padding: 0; }
    .petra-portrait-frame {
      position: relative;
      width: 100%; height: 100%;
      /* Outer frame: warm gilt-cream cardstock */
      background: linear-gradient(165deg, #EAD6A8 0%, #D4B070 55%, #A88753 100%);
      border-radius: 3px;
      padding: 3px;
      transform: rotate(-1.5deg);
      box-shadow:
        inset 0 1px 0 rgba(255,250,235,0.42),
        inset 0 -1px 0 rgba(80,55,20,0.22),
        0 2px 4px rgba(140,110,60,0.20),
        0 6px 14px rgba(80,55,20,0.18);
      transition: transform 0.22s cubic-bezier(0.22,1,0.36,1),
                  box-shadow 0.22s ease;
    }
    /* Inner gold pinstripe — the gilt line that defines the frame */
    .petra-portrait-frame::before {
      content: '';
      position: absolute; inset: 1.5px;
      border: 0.5px solid rgba(255,235,200,0.55);
      border-radius: 2px;
      pointer-events: none;
    }
    /* Outer darker line for depth — sits just inside the frame edge */
    .petra-portrait-frame::after {
      content: '';
      position: absolute; inset: 2.5px;
      border: 0.5px solid rgba(80,55,20,0.32);
      border-radius: 1.5px;
      pointer-events: none;
    }
    /* Mat board — museum cream, with a recessed shadow giving the
       photo well its depth */
    .petra-portrait-mat {
      position: relative;
      width: 100%; height: 100%;
      background: linear-gradient(165deg, #FBF4E3 0%, #F2E8CF 100%);
      border-radius: 1px;
      display: flex; align-items: center; justify-content: center;
      overflow: hidden;
      box-shadow:
        inset 0 1px 2px rgba(80,55,20,0.18),
        inset 0 -0.5px 1px rgba(80,55,20,0.10);
    }
    /* The photo well itself (or the initial monogram when no photo) */
    .petra-portrait-photo {
      width: 30px; height: 30px;
      background: linear-gradient(145deg, #86373E, #6A2A32);
      display: flex; align-items: center; justify-content: center;
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 13px; font-weight: 600;
      color: #EFD9C7;
      overflow: hidden;
      border-radius: 0.5px;
      box-shadow:
        inset 0 0 0 0.5px rgba(80,55,20,0.30),
        inset 0 1px 2px rgba(80,55,20,0.22);
    }
    .petra-portrait-photo img {
      width: 100%; height: 100%;
      object-fit: cover;
      display: block;
    }
    /* Brass photo corners — each is a small triangle filling one
       corner of the frame with a gilt gradient; 0.5px shadow for lift */
    .petra-portrait-corner {
      position: absolute;
      width: 7px; height: 7px;
      background: linear-gradient(135deg, #F0DDA8 0%, #C8A36A 55%, #8A6A3A 100%);
      z-index: 3;
      pointer-events: none;
      box-shadow: 0 0.5px 1px rgba(80,55,20,0.30);
    }
    .petra-portrait-corner-tl {
      top: -0.5px; left: -0.5px;
      clip-path: polygon(0 0, 100% 0, 0 100%);
      border-top-left-radius: 3px;
    }
    .petra-portrait-corner-tr {
      top: -0.5px; right: -0.5px;
      clip-path: polygon(0 0, 100% 0, 100% 100%);
      border-top-right-radius: 3px;
    }
    .petra-portrait-corner-bl {
      bottom: -0.5px; left: -0.5px;
      clip-path: polygon(0 0, 0 100%, 100% 100%);
      border-bottom-left-radius: 3px;
    }
    .petra-portrait-corner-br {
      bottom: -0.5px; right: -0.5px;
      clip-path: polygon(100% 0, 100% 100%, 0 100%);
      border-bottom-right-radius: 3px;
    }
    /* On hover, the frame lifts slightly and straightens — like
       the user is leaning in to look closer */
    .petra-portrait-frame-btn:hover .petra-portrait-frame {
      transform: rotate(-0.5deg) translateY(-1px);
      box-shadow:
        inset 0 1px 0 rgba(255,250,235,0.45),
        inset 0 -1px 0 rgba(80,55,20,0.24),
        0 3px 6px rgba(140,110,60,0.24),
        0 9px 18px rgba(80,55,20,0.20);
    }
    
    /* ═══ CARD AMBIENT ANIMATIONS — Oscar-level character animation ═══ */
    
    /* TODAY: A diary that gently opens — cover lifts to reveal lined pages inside */
    @keyframes today-cover-open {
      0%, 100% { transform: perspective(200px) rotateY(0deg); }
      30% { transform: perspective(200px) rotateY(-55deg); }
      55% { transform: perspective(200px) rotateY(-55deg); }
      85% { transform: perspective(200px) rotateY(0deg); }
    }
    @keyframes today-pages-reveal {
      0%, 100% { opacity: 0; transform: scaleX(0.3); }
      30% { opacity: 0.7; transform: scaleX(1); }
      55% { opacity: 0.7; transform: scaleX(1); }
      85% { opacity: 0; transform: scaleX(0.3); }
    }
    @keyframes today-lines-write {
      0%, 30% { stroke-dashoffset: 20; }
      45% { stroke-dashoffset: 0; }
      55% { stroke-dashoffset: 0; }
      85%, 100% { stroke-dashoffset: 20; }
    }
    .ks-card-1 .card-anim-cover {
      transform-origin: left center;
      animation: today-cover-open 5s ease-in-out infinite;
    }
    .ks-card-1 .card-anim-pages {
      transform-origin: left center;
      animation: today-pages-reveal 5s ease-in-out infinite;
    }
    .ks-card-1 .card-anim-line1 {
      stroke-dasharray: 20; stroke-dashoffset: 20;
      animation: today-lines-write 5s ease-in-out infinite;
    }
    .ks-card-1 .card-anim-line2 {
      stroke-dasharray: 20; stroke-dashoffset: 20;
      animation: today-lines-write 5s ease-in-out 0.15s infinite;
    }
    .ks-card-1 .card-anim-line3 {
      stroke-dasharray: 20; stroke-dashoffset: 20;
      animation: today-lines-write 5s ease-in-out 0.3s infinite;
    }
    
    /* POSTCARD: A card that flips over — front shows image, back reveals handwriting */
    @keyframes postcard-flip {
      0%, 100% { transform: rotateY(0deg); }
      30% { transform: rotateY(180deg); }
      55% { transform: rotateY(180deg); }
      85% { transform: rotateY(0deg); }
    }
    .ks-card-3 .card-anim-flipper {
      animation: postcard-flip 6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
      transform-style: preserve-3d;
    }
    .ks-card-3 .card-anim-front,
    .ks-card-3 .card-anim-back {
      position: absolute; inset: 0;
      backface-visibility: hidden;
      border-radius: 2px;
    }
    .ks-card-3 .card-anim-back {
      transform: rotateY(180deg);
    }
    
    /* TIME CAPSULE: A sealed letter that floats forward into a glowing horizon line — 
       the future receiving your message */
    @keyframes capsule-letter-float {
      0% { transform: translateY(0) scale(1); opacity: 0.7; }
      40% { transform: translateY(-10px) scale(0.85); opacity: 0.8; }
      70% { transform: translateY(-18px) scale(0.6); opacity: 0.4; }
      85% { transform: translateY(-22px) scale(0.4); opacity: 0; }
      86%, 95% { transform: translateY(4px) scale(0); opacity: 0; }
      100% { transform: translateY(0) scale(1); opacity: 0.7; }
    }
    @keyframes capsule-horizon-pulse {
      0%, 100% { opacity: 0.2; transform: scaleX(1); }
      50% { opacity: 0.5; transform: scaleX(1.1); }
      70% { opacity: 0.6; transform: scaleX(1.15); }
      85% { opacity: 0.2; transform: scaleX(1); }
    }
    @keyframes capsule-glow-bloom {
      0%, 100% { opacity: 0; r: 3; }
      65% { opacity: 0; r: 3; }
      80% { opacity: 0.4; r: 8; }
      90% { opacity: 0; r: 12; }
    }
    .ks-card-2 .card-anim-letter { animation: capsule-letter-float 4.5s ease-in-out infinite; }
    .ks-card-2 .card-anim-horizon { animation: capsule-horizon-pulse 4.5s ease-in-out infinite; transform-origin: center; }
    .ks-card-2 .card-anim-glow { animation: capsule-glow-bloom 4.5s ease-in-out infinite; }
    
    /* Capsule ready pulse — golden glow when within 24h or ready to open */
    .capsule-ready-pulse {
      animation: capsule-ready-glow 2.5s ease-in-out infinite !important;
    }
    @keyframes capsule-ready-glow {
      0%, 100% { box-shadow: 0 1px 0 rgba(23,34,43,0.5), 0 2px 4px rgba(15,20,28,0.25), 0 6px 12px rgba(10,14,20,0.15), inset 0 1px 0 rgba(255,255,255,0.04), 0 0 0 0 rgba(241,189,120,0); }
      50% { box-shadow: 0 1px 0 rgba(23,34,43,0.5), 0 2px 4px rgba(15,20,28,0.25), 0 6px 12px rgba(10,14,20,0.15), inset 0 1px 0 rgba(255,255,255,0.04), 0 0 16px 4px rgba(241,189,120,0.15); }
    }
    @keyframes youme-rec-pulse {
      0%, 100% { opacity: 0.4; transform: scale(0.85); }
      50% { opacity: 1; transform: scale(1.1); }
    }
    
    /* VOICECARD: Classic speaker icon with sound wave arcs that pulse outward */
    @keyframes voice-wave1 {
      0%, 100% { opacity: 0.15; transform: scale(0.95); }
      50% { opacity: 0.45; transform: scale(1.05); }
    }
    @keyframes voice-wave2 {
      0%, 100% { opacity: 0.1; transform: scale(0.9); }
      50% { opacity: 0.35; transform: scale(1.08); }
    }
    @keyframes voice-wave3 {
      0%, 100% { opacity: 0.06; transform: scale(0.85); }
      50% { opacity: 0.25; transform: scale(1.1); }
    }
    @keyframes voice-dot-pulse {
      0%, 100% { r: 2.5; opacity: 0.5; }
      50% { r: 3; opacity: 0.7; }
    }
    .ks-card-4 .card-anim-wave1 { animation: voice-wave1 2s ease-in-out infinite; transform-origin: 12px 18px; }
    .ks-card-4 .card-anim-wave2 { animation: voice-wave2 2s ease-in-out 0.2s infinite; transform-origin: 12px 18px; }
    .ks-card-4 .card-anim-wave3 { animation: voice-wave3 2s ease-in-out 0.4s infinite; transform-origin: 12px 18px; }
    .ks-card-4 .card-anim-speaker-dot { animation: voice-dot-pulse 2s ease-in-out infinite; }
    
    /* LETTER: "Writing itself" — the 6 stationery lines draw left-to-right
       with a staggered delay, like an invisible pen filling the page.
       Hold all visible for a beat, then fade together, loop. Slower than
       Postcard's flip (6s) and VoiceCard's wave (2s) so the homescreen
       row feels alive rather than synchronized. */
    @keyframes letter-line-write {
      0%       { transform: scaleX(0); opacity: 0; }
      8%       { opacity: 1; }
      14%      { transform: scaleX(1); opacity: 1; }
      80%      { transform: scaleX(1); opacity: 1; }
      94%      { transform: scaleX(1); opacity: 0; }
      100%     { transform: scaleX(0); opacity: 0; }
    }
    .ks-card-letter .card-anim-letter-line {
      transform-origin: left center;
      animation: letter-line-write 5s cubic-bezier(0.55, 0, 0.45, 1) infinite;
    }
    /* Stagger — each line starts ~0.32s after the previous one, so the
       eye reads the page filling line-by-line like a real letter. */
    .ks-card-letter .card-anim-letter-line:nth-child(1) { animation-delay: 0s; }
    .ks-card-letter .card-anim-letter-line:nth-child(2) { animation-delay: 0.32s; }
    .ks-card-letter .card-anim-letter-line:nth-child(3) { animation-delay: 0.64s; }
    .ks-card-letter .card-anim-letter-line:nth-child(4) { animation-delay: 0.96s; }
    .ks-card-letter .card-anim-letter-line:nth-child(5) { animation-delay: 1.28s; }
    .ks-card-letter .card-anim-letter-line:nth-child(6) { animation-delay: 1.60s; }

    /* GROUPSAKE: Gentle "gift being held forward" — the giftbox SVG floats
       up and back, like a present being lifted to hand over. A soft warm
       glow underneath breathes in sync, giving the box a sense of weight
       + occasion. Replaces the previous shimmer band (which the founder
       called distracting). */
    @keyframes gift-float {
      0%, 100% { transform: translateY(0); }
      50%      { transform: translateY(-3px); }
    }
    @keyframes gift-glow-breathe {
      0%, 100% { opacity: 0; transform: translateX(-50%) scaleX(0.7); }
      50%      { opacity: 0.55; transform: translateX(-50%) scaleX(1); }
    }
    .ks-card-5 .card-anim-gift {
      animation: gift-float 4s ease-in-out infinite;
      will-change: transform;
    }
    /* Soft golden under-glow that pulses in time with the lift */
    .ks-card-5 .card-anim-gift-glow {
      position: absolute;
      left: 50%; bottom: 6px;
      width: 38px; height: 6px;
      background: radial-gradient(ellipse at center, rgba(255,200,120,0.55), transparent 70%);
      border-radius: 50%;
      pointer-events: none;
      animation: gift-glow-breathe 4s ease-in-out infinite;
      will-change: opacity, transform;
      z-index: 1;
    }

    /* Respect reduced-motion preferences for both new animations */
    @media (prefers-reduced-motion: reduce) {
      .ks-card-letter .card-anim-letter-line,
      .ks-card-5 .card-anim-gift,
      .ks-card-5 .card-anim-gift-glow {
        animation: none !important;
      }
      .ks-card-letter .card-anim-letter-line { transform: scaleX(1) !important; opacity: 1 !important; }
    }
    
    /* ═══ KEEPSAKE ENVELOPE ANIMATION KEYFRAMES ═══ */
    
    /* Pulsing ring around seal to invite tap */
    @keyframes sealPulse {
      0%, 100% { transform: scale(1); opacity: 0.6; }
      50% { transform: scale(1.18); opacity: 0; }
    }
    
    /* Subtle breathing on seal itself to emphasize tappability */
    @keyframes sealBreathe {
      0%, 100% { transform: translate(-50%, 0) scale(1); }
      50% { transform: translate(-50%, 0) scale(1.04); }
    }
    
    /* SEND: Postcard slides into envelope */
    @keyframes card-into-envelope {
      0% { transform: translateX(-50%) translateY(0) scale(1); opacity: 1; }
      100% { transform: translateX(-50%) translateY(40px) scale(0.92); opacity: 0; }
    }
    
    /* SEND: Envelope flap closes */
    @keyframes flap-close {
      0% { transform: rotateX(180deg); }
      70% { transform: rotateX(-8deg); }
      85% { transform: rotateX(5deg); }
      100% { transform: rotateX(0deg); }
    }
    
    /* SEND: Wax seal stamps down */
    @keyframes seal-stamp {
      0% { transform: translateX(-50%) scale(2.5); opacity: 0; }
      40% { transform: translateX(-50%) scale(0.9); opacity: 1; }
      60% { transform: translateX(-50%) scale(1.08); opacity: 1; }
      100% { transform: translateX(-50%) scale(1); opacity: 1; }
    }
    
    /* SEND: Sealed envelope floats up INTO the mailbox.
       Was -80→-140→-155 (only reached partway, with the mailbox positioned
       BELOW — narratively wrong). Now travels further upward because the
       mailbox sits ABOVE the envelope stage, and shrinks more aggressively
       so it visually slips inside the mailbox cavity. */
    @keyframes envelope-float-to-mailbox {
      0%   { transform: translateY(0)      scale(1)    rotate(0deg);  opacity: 1; }
      50%  { transform: translateY(-150px) scale(0.65) rotate(-2deg); opacity: 1; }
      85%  { transform: translateY(-260px) scale(0.32) rotate(0deg);  opacity: 0.55; }
      100% { transform: translateY(-300px) scale(0.22) rotate(0deg);  opacity: 0; }
    }

    /* SEND: Wax seal — matches the postcard's voice-note seal aesthetic
       (radial gradient highlight + dark wax body + inner ring + outer
       halo). Used by #env-seal in the send animation overlay. */
    .env-seal-wax {
      position: relative;
      border: 1.5px solid rgba(94, 36, 31, 0.5);
      border-radius: 50%;
      background:
        radial-gradient(circle at 34% 28%, rgba(255, 215, 175, 0.30) 0%, transparent 30%),
        radial-gradient(circle at 55% 62%, #8f352e 0%, #6e211d 56%, #4b1513 100%);
      color: #f7e6c8;
      box-shadow:
        0 3px 6px rgba(55, 30, 18, 0.28),
        0 8px 18px rgba(55, 30, 18, 0.14),
        inset 0 1.5px 2.5px rgba(255, 220, 180, 0.22),
        inset 0 -2.5px 4px rgba(45, 12, 9, 0.32);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      isolation: isolate;
    }
    .env-seal-wax::before {
      content: '';
      position: absolute;
      inset: 6px;
      border-radius: 50%;
      border: 1px solid rgba(247,230,200,0.25);
      box-shadow: inset 0 0 0 1px rgba(45,12,9,0.18);
      pointer-events: none;
    }
    .env-seal-wax::after {
      content: '';
      position: absolute;
      inset: -4px;
      border-radius: 50%;
      background: radial-gradient(circle, rgba(111,33,29,0.20) 0%, transparent 68%);
      z-index: -1;
      pointer-events: none;
    }
    .env-seal-monogram {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 22px;
      font-weight: 700;
      color: #f7e6c8;
      letter-spacing: 0.5px;
      line-height: 1;
      z-index: 1;
      text-shadow: 0 1px 1px rgba(45,12,9,0.45);
    }
    
    /* SEND: Mailbox receives with micro-bounce */
    @keyframes mailbox-receive {
      0% { transform: scale(1); }
      40% { transform: scale(1.03) translateY(1px); }
      100% { transform: scale(1) translateY(0); }
    }
    
    /* SEND: Flag raises */
    @keyframes flag-raise {
      0% { transform: rotate(0deg); }
      60% { transform: rotate(-75deg); }
      80% { transform: rotate(-85deg); }
      100% { transform: rotate(-80deg); }
    }
    
    /* General: Text fades up */
    @keyframes text-fade-up {
      0% { opacity: 0; transform: translateY(12px); }
      100% { opacity: 1; transform: translateY(0); }
    }

    /* ════════════════════════════════════════════════════════════════════
       POSTAL DELIVERY — "Into the Letters Box"
       Single-shot ritual: keepsake is delivered into the Letters mailbox.
       The dove watches. The slot welcomes. The box receives.
       Beats: mailbox enters → keepsake arrives (dove watches) →
              keepsake drops into slot (slot darkens) → box thuds (dove
              flinches) → dove settles, wax seal shimmers → handwriting
              close. Namespaced `lb-` for "letters box". Total ~4.0s.
       ════════════════════════════════════════════════════════════════════ */

    /* Mailbox subtle entrance — scales up gently to settle into the scene */
    @keyframes lb-mailbox-enter {
      0%   { transform: translate(-50%, -50%) scale(0.94); opacity: 0; }
      35%  { opacity: 1; }
      70%  { transform: translate(-50%, -50%) scale(1.025); }
      100% { transform: translate(-50%, -50%) scale(1.00); opacity: 1; }
    }

    /* Keepsake (envelope) arrives from above — like an unseen hand
       brought it. Gentle arc with deceleration, settles just above slot. */
    @keyframes lb-envelope-arrive {
      0%   { transform: translateX(-50%) translateY(-200px) rotate(-12deg); opacity: 0; }
      25%  { opacity: 1; }
      70%  { transform: translateX(-50%) translateY(-30px)  rotate(-7deg);  opacity: 1; }
      100% { transform: translateX(-50%) translateY(-10px)  rotate(-5deg);  opacity: 1; }
    }

    /* Drop into slot — straightens out, slides down, clip-path
       progressively hides the part that's entered the slot. The translate
       distance is tuned to the postbox SVG (slot at y≈115). */
    @keyframes lb-envelope-drop {
      0%   { transform: translateX(-50%) translateY(-10px) rotate(-5deg); clip-path: inset(0 0 0 0); }
      25%  { transform: translateX(-50%) translateY(8px)   rotate(-2deg); clip-path: inset(0 0 0 0); }
      55%  { transform: translateX(-50%) translateY(35px)  rotate(0deg);  clip-path: inset(0 0 40% 0); }
      80%  { transform: translateX(-50%) translateY(65px)  rotate(0deg);  clip-path: inset(0 0 80% 0); }
      100% { transform: translateX(-50%) translateY(90px)  rotate(0deg);  clip-path: inset(0 0 100% 0); opacity: 0; }
    }

    /* Slot mouth darkens as the envelope occupies it. The dark ellipse
       inside the slot brightens (more visible) when something's blocking
       the light from below the slot. */
    @keyframes lb-slot-darken {
      0%   { opacity: 0.25; }
      50%  { opacity: 1.00; }
      100% { opacity: 0.40; }
    }

    /* The mailbox jolts on impact — quick lateral + vertical micro-shake.
       Preserves the parent's translate(-50%, -50%) centering via calc(). */
    @keyframes lb-box-shake {
      0%   { transform: translate(-50%, -50%) scale(1); }
      14%  { transform: translate(calc(-50% - 3px), calc(-50% + 1px)) scale(1); }
      28%  { transform: translate(calc(-50% + 3px), calc(-50% - 1px)) scale(1); }
      42%  { transform: translate(calc(-50% - 2px), calc(-50% + 0.5px)) scale(0.997); }
      58%  { transform: translate(calc(-50% + 1.5px), -50%) scale(1); }
      75%  { transform: translate(calc(-50% - 0.5px), -50%) scale(1); }
      100% { transform: translate(-50%, -50%) scale(1); }
    }

    /* Dove tilts its head up to watch the envelope descend. Pivots at the
       base of the body. -8deg lifts the head; the body axis is roughly
       horizontal-left-to-right with head at right, so CCW rotation raises
       the head. */
    @keyframes lb-dove-watch {
      0%   { transform: rotate(0deg); }
      100% { transform: rotate(-8deg); }
    }
    @keyframes lb-dove-flinch {
      0%, 100% { transform: rotate(-8deg) translateY(0); }
      28%      { transform: rotate(-4deg) translateY(-1px); }
      55%      { transform: rotate(-7deg) translateY(1px); }
      80%      { transform: rotate(-8deg) translateY(0); }
    }
    @keyframes lb-dove-settle {
      0%   { transform: rotate(-8deg); }
      40%  { transform: rotate(-3deg); }
      75%  { transform: rotate(1deg); }
      100% { transform: rotate(0deg); }
    }

    /* The tiny wax seal on the dove's envelope shimmers — an "I see you"
       acknowledgement from the dove to the new arrival. */
    @keyframes lb-seal-shimmer {
      0%, 100% { filter: brightness(1) drop-shadow(0 0 0 transparent); }
      40%      { filter: brightness(1.7) drop-shadow(0 0 4px rgba(220,90,80,0.55)); }
      70%      { filter: brightness(1.3) drop-shadow(0 0 2px rgba(220,90,80,0.35)); }
    }

    /* Handwriting reveal for "Sent with care" — clip-path inset shrinks
       from 100% (fully clipped) to -6px (fully visible, with a small
       negative inset so cursive descenders / italic slant don't get
       trimmed at the right edge). */
    @keyframes lb-handwriting-reveal {
      0%   { clip-path: inset(-6px 100% -6px -6px); }
      100% { clip-path: inset(-6px -6px  -6px -6px); }
    }

    /* Soft drop shadow under the mailbox pulses slightly on shake */
    @keyframes lb-shadow-shake {
      0%, 100% { transform: scaleX(1); opacity: 0.20; }
      30%      { transform: scaleX(0.92); opacity: 0.28; }
      60%      { transform: scaleX(1.04); opacity: 0.16; }
    }

    /* OLD CONCEPT-1 KEYFRAMES (kept below for reference but no longer
       used — playSendAnimation now drives the Letters-Box ritual above) */
    /* ═══════════════════════════════════════════════════════════════════
       CONCEPT 1 — "THE WRITER'S HAND" postal send animation
       Six beats on a writing-desk close-up:
         1) Card settles (drop with bounce + dust puff)
         2) Envelope rises, card slides in (with bulge)
         3) Flap folds (cloth physics + crease flash)
         4) Wax ritual (dropper → drop → splash → signet press → seal reveal)
         5) Envelope lifts off (arcs out of frame)
         6) Handwriting reveal — "Sent with care"
       Animation classes are namespaced `ws-` for "writer's stage".
       Letter variant adds a tri-fold beat (ws-letter-fold) before insertion.
       ═══════════════════════════════════════════════════════════════════ */

    /* Beat 1 — card descends from above and settles with squash/stretch.
       Eases acceleration in, recoil after impact. Translate values match
       the HTML rest position (`top:30px`) so the end state is identity. */
    @keyframes ws-card-settle {
      0%   { transform: translate(-50%, -110px) rotate(-3deg) scale(1.04); opacity: 0; }
      25%  { opacity: 1; }
      75%  { transform: translate(-50%, -4px)   rotate(0deg)  scale(1.00, 1.00); opacity: 1; }
      85%  { transform: translate(-50%, 0px)    rotate(0deg)  scale(1.02, 0.96); opacity: 1; } /* squash on impact */
      93%  { transform: translate(-50%, 0px)    rotate(0deg)  scale(0.99, 1.01); opacity: 1; } /* rebound */
      100% { transform: translate(-50%, 0px)    rotate(0deg)  scale(1.00, 1.00); opacity: 1; }
    }

    /* Beat 1b — dust puff at landing point. Tiny ellipse blooms then dies. */
    @keyframes ws-dust-puff {
      0%   { transform: translate(-50%, 0)  scale(0.35); opacity: 0; }
      20%  { transform: translate(-50%, 0)  scale(0.9);  opacity: 0.45; }
      100% { transform: translate(-50%, 6px) scale(1.9); opacity: 0; }
    }

    /* Beat 1.5 (letters only) — letter folds into thirds before envelope rises.
       Scaling Y from origin top: paper compresses vertically while the top
       edge stays put. Two-stage fold for the satisfying double-crease feel. */
    @keyframes ws-letter-fold {
      0%   { transform: translate(-50%, 0) scaleY(1.00); }
      35%  { transform: translate(-50%, 0) scaleY(0.66); } /* first fold (bottom third folds up) */
      70%  { transform: translate(-50%, 0) scaleY(0.42); } /* second fold */
      85%  { transform: translate(-50%, 0) scaleY(0.34); }
      100% { transform: translate(-50%, 0) scaleY(0.33); }
    }

    /* Beat 2a — envelope rises from below frame. */
    @keyframes ws-envelope-rise {
      0%   { transform: translate(-50%, 90px); opacity: 0; }
      50%  { opacity: 1; }
      100% { transform: translate(-50%, 0);    opacity: 1; }
    }

    /* Beat 2b — card slides into envelope. Tilts forward (entering the mouth),
       moves down 75px, shrinks slightly, fades behind the envelope front. */
    @keyframes ws-card-insert {
      0%   { transform: translate(-50%, 0)    rotateX(0deg)   scale(1.00); opacity: 1; }
      35%  { transform: translate(-50%, 28px) rotateX(-8deg)  scale(0.97); opacity: 1; }
      70%  { transform: translate(-50%, 58px) rotateX(-18deg) scale(0.92); opacity: 0.8; }
      100% { transform: translate(-50%, 80px) rotateX(-26deg) scale(0.86); opacity: 0; }
    }

    /* Beat 2c — envelope edges bulge briefly as card enters (squash + stretch). */
    @keyframes ws-envelope-bulge {
      0%, 100% { transform: translate(-50%, 0) scale(1.000, 1.000); }
      30%      { transform: translate(-50%, 0) scale(1.015, 1.005); }
      60%      { transform: translate(-50%, 0) scale(1.008, 0.998); }
    }

    /* Beat 3a — flap folds with cloth physics. Hesitates at top (sticky paper),
       accelerates under gravity, overshoots closed, recoils, settles. */
    @keyframes ws-flap-fold-cloth {
      0%   { transform: rotateX(180deg); }
      8%   { transform: rotateX(174deg); } /* sticky hesitation */
      20%  { transform: rotateX(158deg); }
      38%  { transform: rotateX(108deg); } /* gravity accelerates */
      58%  { transform: rotateX(46deg); }
      76%  { transform: rotateX(6deg); }
      86%  { transform: rotateX(-4deg); }  /* overshoot */
      93%  { transform: rotateX(2deg); }   /* recoil */
      100% { transform: rotateX(0deg); }   /* settled */
    }

    /* Beat 3b — crease flash where flap meets body. One frame of brighter
       light to register the contact moment (paper kisses paper). */
    @keyframes ws-crease-flash {
      0%, 75% { opacity: 0; }
      82%     { opacity: 0.70; }
      100%    { opacity: 0; }
    }

    /* Beat 4a — wax dropper descends into frame from above. */
    @keyframes ws-dropper-dip {
      0%   { transform: translate(-50%, -50px); opacity: 0; }
      50%  { opacity: 1; }
      100% { transform: translate(-50%, 0);     opacity: 1; }
    }

    /* Beat 4b — drop forms at the dropper tip (grows from 0 to full). */
    @keyframes ws-drop-form {
      0%   { transform: translate(-50%, 0) scale(0, 0); }
      100% { transform: translate(-50%, 0) scale(1, 1); }
    }

    /* Beat 4c — drop separates and falls. Stretches as it accelerates,
       squashes flat on impact at the flap surface. */
    @keyframes ws-drop-fall {
      0%   { transform: translate(-50%, 0)    scale(1.00, 1.00); opacity: 1; }
      55%  { transform: translate(-50%, 24px) scale(0.85, 1.35); opacity: 1; } /* stretched mid-flight */
      88%  { transform: translate(-50%, 42px) scale(1.30, 0.55); opacity: 1; } /* squashed on impact */
      100% { transform: translate(-50%, 42px) scale(1.30, 0.55); opacity: 0; }
    }

    /* Beat 4d — ripple ring expands outward from the wax-drop impact.
       Horizontal centering via translateX(-50%); the element is positioned
       so its TOP edge sits at the V-tip Y minus half height — no vertical
       transform centering needed. */
    @keyframes ws-ripple {
      0%   { transform: translateX(-50%) scale(0.25); opacity: 0.55; }
      100% { transform: translateX(-50%) scale(2.8);  opacity: 0; }
    }

    /* Beat 4e — wax blob (un-stamped) settles into its resting shape. */
    @keyframes ws-blob-settle {
      0%   { transform: translateX(-50%) scale(1.4, 0.5); opacity: 0; }
      8%   { opacity: 1; }
      35%  { transform: translateX(-50%) scale(0.92, 1.06); }
      65%  { transform: translateX(-50%) scale(1.04, 0.98); }
      100% { transform: translateX(-50%) scale(1.00, 1.00); opacity: 1; }
    }

    /* Beat 4f — signet ring descends, presses, holds, lifts away. */
    @keyframes ws-signet-press {
      0%   { transform: translateX(-50%) translateY(-32px) scale(1.00); opacity: 0; }
      28%  { transform: translateX(-50%) translateY(-3px)  scale(1.00); opacity: 1; } /* arrived above wax */
      42%  { transform: translateX(-50%) translateY(3px)   scale(1.05); opacity: 1; } /* pressing */
      62%  { transform: translateX(-50%) translateY(3px)   scale(1.05); opacity: 1; } /* hold */
      100% { transform: translateX(-50%) translateY(-36px) scale(1.00); opacity: 0; } /* lift away */
    }

    /* Beat 4g — wax blob compresses under the signet press. */
    @keyframes ws-wax-under-press {
      0%   { transform: translateX(-50%) scale(1.00, 1.00); }
      42%, 62% { transform: translateX(-50%) scale(1.08, 0.88); }
      100% { transform: translateX(-50%) scale(1.00, 1.00); }
    }

    /* Beat 4h — final wax seal (with P monogram) is revealed as the signet
       lifts away. Crossfades from the un-stamped blob. */
    @keyframes ws-seal-reveal {
      0%   { opacity: 0; transform: translateX(-50%) scale(0.94); }
      40%  { opacity: 0; transform: translateX(-50%) scale(0.94); }
      75%  { opacity: 1; transform: translateX(-50%) scale(1.05); }
      100% { opacity: 1; transform: translateX(-50%) scale(1.00); }
    }

    /* Beat 5 — envelope lifts off the desk and arcs up out of frame. */
    @keyframes ws-envelope-liftoff {
      0%   { transform: translate(-50%, 0)      rotate(0deg)  scale(1.00); opacity: 1; }
      20%  { transform: translate(-50%, -18px)  rotate(2deg)  scale(1.00); opacity: 1; }
      100% { transform: translate(-50%, -300px) rotate(-4deg) scale(0.55); opacity: 0; }
    }

    /* Beat 6 — handwriting reveal: right inset shrinks from 100% to 0%,
       text is unmasked left → right as if a pen is writing it. */
    @keyframes ws-handwriting-reveal {
      0%   { clip-path: inset(0 100% 0 0); }
      100% { clip-path: inset(0 0%   0 0); }
    }

    /* Wax seal (final stamped) — matches voice-seal aesthetic. Used by
       #env-seal in the new send animation. */
    .env-seal-wax {
      position: relative;
      border: 1.5px solid rgba(94, 36, 31, 0.5);
      border-radius: 50%;
      background:
        radial-gradient(circle at 34% 28%, rgba(255, 215, 175, 0.32) 0%, transparent 30%),
        radial-gradient(circle at 55% 62%, #8f352e 0%, #6e211d 56%, #4b1513 100%);
      color: #f7e6c8;
      box-shadow:
        0 3px 6px rgba(55, 30, 18, 0.30),
        0 8px 18px rgba(55, 30, 18, 0.14),
        inset 0 1.5px 2.5px rgba(255, 220, 180, 0.24),
        inset 0 -2.5px 4px rgba(45, 12, 9, 0.34);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      isolation: isolate;
    }
    .env-seal-wax::before {
      content: '';
      position: absolute;
      inset: 6px;
      border-radius: 50%;
      border: 1px solid rgba(247,230,200,0.25);
      box-shadow: inset 0 0 0 1px rgba(45,12,9,0.18);
      pointer-events: none;
    }
    .env-seal-wax::after {
      content: '';
      position: absolute;
      inset: -4px;
      border-radius: 50%;
      background: radial-gradient(circle, rgba(111,33,29,0.22) 0%, transparent 68%);
      z-index: -1;
      pointer-events: none;
    }
    .env-seal-monogram {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 22px;
      font-weight: 700;
      color: #f7e6c8;
      letter-spacing: 0.5px;
      line-height: 1;
      z-index: 1;
      text-shadow: 0 1px 1px rgba(45,12,9,0.45);
    }

    /* Letter representation — folded paper used in the letter-variant animation.
       Two horizontal fold crease lines hint at the trifold. */
    .ws-folded-letter {
      width: 140px;
      height: 200px;
      background: linear-gradient(180deg, #f8f1de 0%, #ede1c2 100%);
      border-radius: 2px;
      box-shadow: 0 2px 6px rgba(60,40,20,0.18), inset 0 0 30px rgba(170,140,90,0.10);
      position: relative;
      transform-origin: top center;
      overflow: hidden;
    }
    .ws-folded-letter::before,
    .ws-folded-letter::after {
      content: '';
      position: absolute;
      left: 8px;
      right: 8px;
      height: 1px;
      background: rgba(120,90,55,0.15);
      box-shadow: 0 1px 0 rgba(255,250,235,0.45);
    }
    .ws-folded-letter::before { top: 33.33%; }
    .ws-folded-letter::after  { top: 66.66%; }
    .ws-folded-letter .ws-letter-lines {
      position: absolute;
      inset: 16px 14px;
      display: flex;
      flex-direction: column;
      gap: 8px;
    }
    .ws-folded-letter .ws-letter-lines > div {
      height: 1.5px;
      background: linear-gradient(90deg, rgba(80,55,30,0.40) 0%, rgba(80,55,30,0.25) 70%, transparent 100%);
      border-radius: 1px;
    }
    .ws-folded-letter .ws-letter-lines > div:nth-child(1) { width: 78%; }
    .ws-folded-letter .ws-letter-lines > div:nth-child(2) { width: 92%; }
    .ws-folded-letter .ws-letter-lines > div:nth-child(3) { width: 65%; }
    .ws-folded-letter .ws-letter-lines > div:nth-child(4) { width: 88%; }
    .ws-folded-letter .ws-letter-lines > div:nth-child(5) { width: 72%; }
    .ws-folded-letter .ws-letter-sig {
      position: absolute;
      bottom: 12px;
      right: 14px;
      font-family: 'Caveat', 'Dancing Script', cursive;
      font-size: 14px;
      color: rgba(60, 35, 20, 0.65);
      transform: rotate(-3deg);
    }
    
    /* RECEIVE: Wax seal cracks open (legacy — kept for compat) */
    @keyframes seal-crack {
      0% { transform: translateX(-50%) scale(1); opacity: 1; }
      50% { transform: translateX(-50%) scale(1.15); opacity: 0.8; }
      100% { transform: translateX(-50%) scale(1.5); opacity: 0; }
    }
    
    /* RECEIVE: Wax breaks — left half flies left */
    @keyframes seal-break-left {
      0% { transform: translateX(0) translateY(0) rotate(0deg); opacity: 1; }
      30% { transform: translateX(-8px) translateY(-2px) rotate(-12deg); opacity: 1; }
      100% { transform: translateX(-40px) translateY(28px) rotate(-45deg); opacity: 0; }
    }
    
    /* RECEIVE: Wax breaks — right half flies right */
    @keyframes seal-break-right {
      0% { transform: translateX(0) translateY(0) rotate(0deg); opacity: 1; }
      30% { transform: translateX(8px) translateY(-2px) rotate(12deg); opacity: 1; }
      100% { transform: translateX(40px) translateY(28px) rotate(45deg); opacity: 0; }
    }
    
    /* RECEIVE: Card emerges from envelope (slides up + forward in 3D) */
    @keyframes card-emerge-3d {
      0% { 
        transform: translateX(-50%) translateY(0) translateZ(0) scale(1);
        opacity: 0;
      }
      15% { opacity: 1; }
      60% {
        transform: translateX(-50%) translateY(-90px) translateZ(40px) scale(1.02);
        opacity: 1;
      }
      100% {
        transform: translateX(-50%) translateY(-110px) translateZ(60px) scale(1.05);
        opacity: 1;
      }
    }
    
    /* RECEIVE: V-flap opens — heavy "settled paper" easing.
       Three-stage motion: sticky resistance (0–18%) from broken-seal residue,
       gravity-style fall (18–70%) as the flap accelerates downward in space,
       then a slow decelerating settle (70–100%) — no spring overshoot. */
    @keyframes flap-open-real {
      0%   { transform: rotateX(0deg); }
      8%   { transform: rotateX(-4deg); }
      18%  { transform: rotateX(-14deg); }
      35%  { transform: rotateX(-52deg); }
      55%  { transform: rotateX(-118deg); }
      72%  { transform: rotateX(-155deg); }
      88%  { transform: rotateX(-171deg); }
      100% { transform: rotateX(-175deg); }
    }

    /* RECEIVE: Card grows to fill viewport (final transition) */
    @keyframes card-grow-to-viewer {
      0% { 
        transform: translateX(-50%) translateY(-110px) translateZ(60px) scale(1.05);
        opacity: 1;
      }
      100% { 
        transform: translateX(-50%) translateY(-50%) translateZ(0) scale(1.6);
        opacity: 0;
      }
    }
    
    /* Envelope perspective container */
    .envelope-perspective {
      perspective: 1400px;
      transform-style: preserve-3d;
    }
    
    .animate-up { animation: fadeUp 0.6s var(--ease-settle) forwards; }
    .animate-pulse-slow { animation: pulse-slow 6s ease-in-out infinite; }
    .delay-1 { animation-delay: 0.15s; opacity: 0; }
    .delay-2 { animation-delay: 0.3s; opacity: 0; }
    
    .postcard-shadow {
      box-shadow: 
        /* Card stock thickness — visible paper edge */
        0 1px 0 rgba(180,160,130,0.4),
        0 2px 0 rgba(160,140,110,0.25),
        0 3px 0 rgba(140,120,95,0.15),
        /* Tight contact shadow */
        0 4px 6px rgba(80,60,40,0.18),
        /* Medium spread — object resting on surface */
        0 8px 16px rgba(60,40,20,0.12),
        /* Soft ambient occlusion */
        0 16px 32px rgba(40,25,10,0.08),
        /* Inner pressed-paper emboss on edges */
        inset 0 1px 0 rgba(255,250,240,0.5),
        inset 0 -1px 0 rgba(120,100,70,0.08),
        inset 1px 0 0 rgba(255,250,240,0.25),
        inset -1px 0 0 rgba(120,100,70,0.06);
    }
    
    .stamp-edge {
      clip-path: polygon(4% 0%,8% 4%,12% 0%,16% 4%,20% 0%,24% 4%,28% 0%,32% 4%,36% 0%,40% 4%,44% 0%,48% 4%,52% 0%,56% 4%,60% 0%,64% 4%,68% 0%,72% 4%,76% 0%,80% 4%,84% 0%,88% 4%,92% 0%,96% 4%,100% 0%,100% 4%,96% 8%,100% 12%,96% 16%,100% 20%,96% 24%,100% 28%,96% 32%,100% 36%,96% 40%,100% 44%,96% 48%,100% 52%,96% 56%,100% 60%,96% 64%,100% 68%,96% 72%,100% 76%,96% 80%,100% 84%,96% 88%,100% 92%,96% 96%,100% 100%,96% 100%,92% 96%,88% 100%,84% 96%,80% 100%,76% 96%,72% 100%,68% 96%,64% 100%,60% 96%,56% 100%,52% 96%,48% 100%,44% 96%,40% 100%,36% 96%,32% 100%,28% 96%,24% 100%,20% 96%,16% 100%,12% 96%,8% 100%,4% 96%,0% 100%,0% 96%,4% 92%,0% 88%,4% 84%,0% 80%,4% 76%,0% 72%,4% 68%,0% 64%,4% 60%,0% 56%,4% 52%,0% 48%,4% 44%,0% 40%,4% 36%,0% 32%,4% 28%,0% 24%,4% 20%,0% 16%,4% 12%,0% 8%,4% 4%);
    }

    /* The byline-only inline label is hidden by default; the byline
       design opts into showing it via the rule below. */
    .vc-byline-audio-label { display: none; }


    /* ════════════════════════════════════════════════════════════
       VOICECARD DESIGN — THE BYLINE
       FORM: tall narrow BOOK SPINE (1 × 3 ratio, ~150 × 450). Cloth
       maroon binding with gilt page-block edges; sender's name runs
       vertically in gilt up the spine like the byline on a treasured
       volume. Title sits at top as a chapter mark; photo small below;
       audio + imprint at the bottom — same banded hierarchy a real
       bound book carries. Still: type as architecture,
       but now also AS the architecture.
       ──────────────────────────────────────────────────────────── */

    /* Outer "binding" — burgundy cloth (linen-weave SVG overlay) with
       gilt page-block edges (inset gold rules on left + right). */
    .vc-card-frame.vc-design-byline {
      background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cg stroke='%23000' stroke-width='0.5' opacity='0.18'%3E%3Cline x1='0' y1='2' x2='8' y2='2'/%3E%3Cline x1='0' y1='6' x2='8' y2='6'/%3E%3Cline x1='2' y1='0' x2='2' y2='8'/%3E%3Cline x1='6' y1='0' x2='6' y2='8'/%3E%3C/g%3E%3C/svg%3E"),
        linear-gradient(178deg, #5A1A1B 0%, #4A1215 50%, #3D0E10 100%) !important;
      background-size: 8px 8px, auto !important;
      background-repeat: repeat, no-repeat !important;
      aspect-ratio: 1 / 3 !important;
      max-width: 150px !important;
      padding: 6px 4px !important;
      border-radius: 2px !important;
      box-shadow:
        0 6px 18px rgba(0,0,0,0.45),
        0 18px 44px rgba(0,0,0,0.30),
        inset 2px 0 0 rgba(201,169,97,0.50),
        inset -2px 0 0 rgba(201,169,97,0.50),
        inset 0 1px 0 rgba(255,235,170,0.20) !important;
    }
    .vc-design-byline .vc-accent-line {
      border-color: rgba(201,169,97,0.45) !important;
      inset: 4px !important;
    }
    .vc-design-byline .vc-mid-border {
      background: linear-gradient(178deg, #5A1A1B 0%, #3D0E10 100%) !important;
      padding: 12px 4px !important;
      clip-path: none !important;
      border-top: 2px double #C9A961 !important;
      border-bottom: 2px double #C9A961 !important;
      box-shadow: none !important;
    }
    .vc-design-byline .vc-mid-scallop {
      border: none !important;
      clip-path: none !important;
      inset: 0 !important;
    }
    .vc-design-byline #vc-card-color-main {
      background: transparent !important;
    }
    .vc-design-byline .vc-content {
      padding: 8px 4px !important;
      display: flex !important;
      flex-direction: column;
      align-items: center;
      height: 100%;
      gap: 6px;
    }

    /* Title at top — small horizontal type, like a chapter mark */
    .vc-design-byline .vc-title-block {
      margin: 0 !important;
      width: 100%;
      flex-shrink: 0;
    }
    .vc-design-byline .vc-title-block > div:first-child {
      font-family: 'Bodoni Moda', 'Cormorant Garamond', Georgia, serif !important;
      font-size: 9px !important;
      font-weight: 600 !important;
      font-style: normal !important;
      letter-spacing: 0.20em !important;
      text-transform: uppercase !important;
      color: rgba(201,169,97,0.85) !important;
      text-align: center !important;
      min-height: 12px !important;
      text-shadow: 0 1px 0 rgba(0,0,0,0.40) !important;
    }
    .vc-design-byline .vc-title-rule {
      width: 28px !important;
      background: linear-gradient(90deg, transparent, rgba(201,169,97,0.55), transparent) !important;
      margin: 4px auto 0 !important;
    }

    /* Sender section — small photo at top, name vertical below dominates */
    .vc-design-byline .vc-sender-section {
      display: flex !important;
      flex-direction: column !important;
      align-items: center !important;
      gap: 8px !important;
      margin: 4px 0 !important;
      flex: 1 1 auto;
      width: 100%;
/* min-height inherited from .kp-card base */
    }
    .vc-design-byline .vc-from-caption { display: none !important; }
    .vc-design-byline .vc-sender-info {
      flex: 1 1 auto;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
/* min-height inherited from .kp-card base */
    }
    /* Photo grows to fill the spine's horizontal space — was a tiny
       30×38 wafer, now a proper 50×64 portrait that uses the room
       the spine offers. Subtle gilt double-rim makes it feel mounted
       inside the bookbinding rather than dropped into it. */
    .vc-design-byline .vc-photo-frame {
      width: 50px !important;
      height: 64px !important;
      border-radius: 1px !important;
      background: linear-gradient(145deg, #EDE8E0, #E4DDD4) !important;
      border: 0.5px solid #C9A961 !important;
      box-shadow:
        0 0 0 1px rgba(201,169,97,0.45),
        0 0 0 2px rgba(90,26,27,0.85),
        0 1px 3px rgba(0,0,0,0.40) !important;
      flex-shrink: 0;
    }

    /* THE BYLINE MOMENT — sender's name running VERTICALLY up the
       spine in gilt italic Bodoni. writing-mode: vertical-rl rotates
       the glyphs so they read top-to-bottom along the spine, exactly
       like a real bound-book byline. The transform: rotate(180deg)
       flips it so the name reads bottom-up (the standard convention
       for English book spines worldwide). */
    .vc-design-byline .vc-sender-name {
      writing-mode: vertical-rl !important;
      text-orientation: mixed;
      transform: rotate(180deg);
      font-family: 'Bodoni Moda', 'Playfair Display', Georgia, serif !important;
      font-size: 32px !important;
      font-weight: 500 !important;
      font-style: italic !important;
      letter-spacing: -0.015em !important;
      line-height: 1 !important;
      color: #C9A961 !important;
      text-shadow:
        0 1px 0 rgba(0,0,0,0.45),
        0 -0.5px 0 rgba(255,235,170,0.20) !important;
      margin: 0 !important;
      padding: 0 !important;
      white-space: nowrap;
      overflow: hidden;
      max-height: 100%;
      text-align: center;
    }

    /* Audio at the bottom — compact play button + sparse waveform.
       Only every 4th wave bar renders so the row fits the spine width
       and reads as a thin gilt rhythm rather than a fat solid block. */
    .vc-design-byline .vc-audio-block {
      margin: 0 !important;
      flex-shrink: 0;
      width: 100%;
    }
    .vc-design-byline .vc-audio-panel {
      background: transparent !important;
      border: none !important;
      padding: 0 !important;
      border-radius: 0 !important;
    }
    .vc-design-byline .vc-audio-row {
      gap: 6px !important;
      justify-content: center !important;
    }
    .vc-design-byline .vc-play-btn {
      width: 26px !important;
      height: 26px !important;
      background: radial-gradient(circle at 35% 30%, #DCC079, #826417) !important;
      box-shadow:
        0 1px 2px rgba(0,0,0,0.45),
        inset 0 1px 1px rgba(255,235,170,0.30) !important;
    }
    .vc-design-byline .vc-play-icon {
      fill: #2A1A05 !important;
      width: 10px !important;
      height: 10px !important;
    }
    .vc-design-byline .vc-waveform-wrap { max-width: 70px !important; }
    .vc-design-byline .vc-wave-bar {
      background: linear-gradient(180deg, #DCC079, #826417) !important;
      width: 1px !important;
    }
    .vc-design-byline .vc-wave-bar:not(:nth-child(4n)) { display: none !important; }
    .vc-design-byline .vc-audio-bottom-row { display: none !important; }

    /* Imprint at very bottom — tiny gilt label, like a publisher's
       mark at the foot of a real spine. */
    .vc-design-byline .vc-imprint {
      border-top: none !important;
      padding-top: 4px !important;
      margin-top: 4px !important;
      flex-shrink: 0;
      text-align: center !important;
    }
    .vc-design-byline .vc-imprint-primary {
      font-family: 'Bodoni Moda', Georgia, serif !important;
      font-size: 7px !important;
      font-weight: 600 !important;
      font-style: normal !important;
      letter-spacing: 0.18em !important;
      text-transform: uppercase !important;
      color: rgba(201,169,97,0.65) !important;
      text-shadow: 0 1px 0 rgba(0,0,0,0.30) !important;
    }
    .vc-design-byline .vc-imprint-date::before { content: "" !important; }
    .vc-design-byline .vc-imprint-secondary { display: none !important; }

    /* ════════════════════════════════════════════════════════════
       Imprint base — serial prefix variants are HIDDEN by default;
       each design opts the right one IN below. All English. No
       borrowed Latin/Japanese conventions in the markup.
       ──────────────────────────────────────────────────────────── */
    .vc-serial-reel,
    .vc-serial-tag,
    .vc-serial-ref { display: none; }

    /* ════════════════════════════════════════════════════════════
       VOICECARD DESIGN — THE PHONOGRAPH
       FORM: perfect circular DISC (320 × 320). Bakelite-black outer
       rim with concentric grooves; cream center label holds title +
       sender + audio + imprint. Real silhouette break — round among
       rectangles. Reads instantly as "this is a recording."
       ──────────────────────────────────────────────────────────── */
    .vc-card-frame.vc-design-phonograph {
      background:
        repeating-radial-gradient(circle at center,
          transparent 0 1px,
          rgba(255,235,200,0.05) 1px 2px),
        radial-gradient(circle at 30% 30%,
          #2A1F18 0%,
          #1A120D 40%,
          #0E0A07 80%,
          #050302 100%) !important;
      border-radius: 50% !important;
      aspect-ratio: 1 !important;
      max-width: 320px !important;
      padding: 14px !important;
      box-shadow:
        0 6px 18px rgba(0,0,0,0.45),
        0 18px 48px rgba(0,0,0,0.30),
        inset 0 1px 0 rgba(180,150,110,0.18) !important;
    }
    .vc-design-phonograph .vc-accent-line {
      inset: 12px !important;
      border: 0.5px solid rgba(212,180,140,0.35) !important;
      border-radius: 50% !important;
    }
    .vc-design-phonograph .vc-mid-border {
      background:
        repeating-radial-gradient(circle at center,
          rgba(255,255,255,0.06) 0 1px,
          rgba(0,0,0,0.30) 1px 3px),
        radial-gradient(circle at 30% 30%, #181210, #0A0807) !important;
      border-radius: 50% !important;
      padding: 48px !important;
      clip-path: none !important;
      box-shadow:
        inset 0 0 0 1.5px rgba(201,169,97,0.55),
        inset 0 0 14px rgba(0,0,0,0.50) !important;
    }
    .vc-design-phonograph .vc-mid-scallop {
      border: 1px solid rgba(201,169,97,0.45) !important;
      border-radius: 50% !important;
      clip-path: none !important;
    }
    .vc-design-phonograph #vc-card-color-main {
      border-radius: 50% !important;
      box-shadow:
        inset 0 0 0 1px rgba(201,169,97,0.45),
        inset 0 0 8px rgba(80,55,15,0.10) !important;
    }
    .vc-design-phonograph .vc-content {
      padding: 26px 22px 22px !important;
      text-align: center;
    }
    .vc-design-phonograph .vc-title-block { margin: 0 0 8px !important; }
    .vc-design-phonograph .vc-title-block > div:first-child {
      font-family: 'Bodoni Moda', 'Playfair Display', Georgia, serif !important;
      font-size: 16px !important;
      font-weight: 600 !important;
      font-style: italic !important;
      letter-spacing: 0.02em !important;
      color: #2A1212 !important;
      min-height: 18px !important;
    }
    .vc-design-phonograph .vc-title-rule { display: none !important; }
    .vc-design-phonograph .vc-sender-section {
      gap: 8px !important;
      margin-bottom: 10px !important;
    }
    /* Photo grows from a 32×40 thumbnail to a 44×56 proper portrait —
       sits to the left of the sender info inside the cream center label
       with consistent vertical alignment. Adds a thin gilt rim so the
       photo reads as a label sticker on the record's centre. */
    .vc-design-phonograph .vc-photo-frame {
      width: 44px !important;
      height: 56px !important;
      border-radius: 1px !important;
      border: 0.5px solid rgba(140,110,80,0.45) !important;
      box-shadow:
        0 0 0 1px rgba(201,169,97,0.30),
        0 1px 2px rgba(40,15,15,0.18) !important;
    }
    /* Re-balance the sender row now that the photo is larger.
       Vertical-align baseline of "from" + name to the photo's centre. */
    .vc-design-phonograph .vc-sender-section {
      align-items: center !important;
    }
    .vc-design-phonograph .vc-sender-info {
      text-align: left !important;
    }
    .vc-design-phonograph .vc-from-caption {
      font-size: 8px !important;
      letter-spacing: 0.20em !important;
      color: rgba(80,40,20,0.55) !important;
    }
    .vc-design-phonograph .vc-sender-name {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-size: 14px !important;
      font-style: italic !important;
      color: #2A1212 !important;
    }
    .vc-design-phonograph .vc-audio-block { margin: 8px 0 !important; }
    .vc-design-phonograph .vc-audio-panel {
      background: transparent !important;
      border: none !important;
      padding: 0 !important;
    }
    .vc-design-phonograph .vc-play-btn {
      width: 36px !important;
      height: 36px !important;
      background: radial-gradient(circle at 35% 30%, #C9A961, #826417) !important;
      box-shadow:
        0 1px 3px rgba(0,0,0,0.50),
        inset 0 1px 1px rgba(255,235,170,0.30) !important;
    }
    .vc-design-phonograph .vc-play-icon {
      fill: #1A0D08 !important;
      width: 14px !important;
      height: 14px !important;
    }
    .vc-design-phonograph .vc-wave-bar {
      background: linear-gradient(180deg, #4A2018, #2A1212) !important;
      width: 1.5px !important;
    }
    .vc-design-phonograph .vc-wave-bar:nth-child(2n) { display: none !important; }
    .vc-design-phonograph .vc-audio-bottom-row { display: none !important; }
    .vc-design-phonograph .vc-imprint {
      border-top: 0.5px solid rgba(140,110,80,0.20) !important;
      padding-top: 8px !important;
    }
    .vc-design-phonograph .vc-imprint-primary {
      font-family: 'Bodoni Moda', Georgia, serif !important;
      font-size: 9px !important;
      letter-spacing: 0.16em !important;
      text-transform: uppercase !important;
      color: rgba(80,40,20,0.65) !important;
      font-weight: 600 !important;
      font-style: normal !important;
    }
    .vc-design-phonograph .vc-imprint-date::before {
      content: "Side A · ";
      color: rgba(80,40,20,0.45);
    }
    .vc-design-phonograph .vc-imprint-secondary {
      font-family: 'Bodoni Moda', Georgia, serif !important;
      font-size: 9px !important;
      letter-spacing: 0.16em !important;
      text-transform: uppercase !important;
      color: rgba(80,40,20,0.45) !important;
      font-weight: 600 !important;
      font-style: normal !important;
    }
    .vc-design-phonograph .vc-imprint-time { display: none !important; }
    .vc-design-phonograph .vc-imprint-divider { display: none !important; }
    .vc-design-phonograph .vc-serial-default { display: none !important; }
    .vc-design-phonograph .vc-serial-reel {
      display: inline !important;
      color: rgba(80,40,20,0.65) !important;
    }


    /* ════════════════════════════════════════════════════════════
       VOICECARD DESIGN — THE LOCKET
       FORM: tall OVAL (5 × 7 ratio). Gold rim + decorative clasp at
       top. Photo dominant as oval cameo nested inside. Intimate,
       worn-close keepsake form — silhouette break from rectangle to
       ellipse.
       ──────────────────────────────────────────────────────────── */
    .vc-card-frame.vc-design-locket {
      background: linear-gradient(160deg, #C9A961 0%, #A88339 35%, #826417 75%, #5A4410 100%) !important;
      border-radius: 50% !important;
      aspect-ratio: 5 / 7 !important;
      max-width: 280px !important;
      padding: 4px !important;
      margin-top: 24px !important;
      box-shadow:
        0 4px 14px rgba(80,55,10,0.40),
        0 18px 44px rgba(80,55,10,0.20),
        inset 0 1px 0 rgba(255,235,170,0.40) !important;
    }
    .vc-card-frame.vc-design-locket::before {
      content: "";
      position: absolute;
      top: -16px;
      left: 50%;
      transform: translateX(-50%);
      width: 22px;
      height: 22px;
      border: 2px solid #826417;
      border-radius: 50%;
      background: radial-gradient(circle at 35% 30%, #DCC079, #826417);
      box-shadow: 0 2px 4px rgba(40,25,5,0.50), inset 0 1px 0 rgba(255,235,170,0.30);
      pointer-events: none;
      z-index: 6;
    }
    .vc-card-frame.vc-design-locket::after {
      content: "";
      position: absolute;
      top: -2px;
      left: 50%;
      transform: translateX(-50%);
      width: 8px;
      height: 6px;
      background: linear-gradient(180deg, #826417, #5A4410);
      pointer-events: none;
      z-index: 5;
    }
    .vc-design-locket .vc-accent-line {
      border-radius: 50% !important;
      inset: 3px !important;
      border-color: rgba(255,235,170,0.55) !important;
    }
    .vc-design-locket .vc-mid-border {
      background: linear-gradient(178deg, #FBF4E3 0%, #F4ECDA 100%) !important;
      border-radius: 50% !important;
      padding: 8px !important;
      clip-path: none !important;
      box-shadow: inset 0 0 0 0.5px rgba(168,131,57,0.40) !important;
    }
    .vc-design-locket .vc-mid-scallop {
      border-radius: 50% !important;
      border: 0.5px dashed rgba(168,131,57,0.35) !important;
      clip-path: none !important;
    }
    .vc-design-locket #vc-card-color-main {
      border-radius: 50% !important;
    }
    .vc-design-locket .vc-content {
      padding: 26px 30px 26px !important;
      text-align: center;
      display: flex !important;
      flex-direction: column;
      gap: 6px;
    }
    .vc-design-locket .vc-sender-section { order: 1 !important; }
    .vc-design-locket .vc-title-block    { order: 2 !important; }
    .vc-design-locket .vc-audio-block    { order: 3 !important; }
    .vc-design-locket .vc-transcript     { order: 4 !important; }
    .vc-design-locket .vc-note-block     { order: 5 !important; }
    .vc-design-locket .vc-imprint        { order: 6 !important; }
    .vc-design-locket .vc-sender-section {
      display: flex !important;
      flex-direction: column !important;
      align-items: center !important;
      gap: 6px !important;
      margin: 0 !important;
    }
    .vc-design-locket .vc-from-caption { display: none !important; }
    .vc-design-locket .vc-sender-info { text-align: center !important; }
    .vc-design-locket .vc-photo-frame {
      width: 72px !important;
      height: 92px !important;
      border-radius: 50% !important;
      background: linear-gradient(145deg, #FAF3E5, #EDE2C8) !important;
      border: 1.5px solid #A88339 !important;
      box-shadow:
        inset 0 1px 3px rgba(120,90,40,0.20),
        0 0 0 2px #FAF3E5,
        0 0 0 3px rgba(168,131,57,0.55),
        0 1px 3px rgba(0,0,0,0.18) !important;
      overflow: hidden !important;
    }
    .vc-design-locket .vc-photo-frame > img { border-radius: 50% !important; }
    .vc-design-locket .vc-title-block { margin: 0 !important; }
    .vc-design-locket .vc-title-block > div:first-child {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-size: 18px !important;
      font-style: italic !important;
      font-weight: 500 !important;
      color: #5A4410 !important;
      min-height: 20px !important;
    }
    .vc-design-locket .vc-title-rule {
      width: 30px !important;
      background: linear-gradient(90deg, transparent, rgba(168,131,57,0.55), transparent) !important;
      margin: 4px auto 0 !important;
    }
    .vc-design-locket .vc-sender-name {
      font-family: 'Great Vibes', 'Cormorant Garamond', cursive !important;
      font-size: 22px !important;
      color: #826417 !important;
      font-style: normal !important;
      margin: 0 !important;
    }
    .vc-design-locket .vc-audio-block { margin: 4px 0 !important; }
    .vc-design-locket .vc-audio-panel {
      background: transparent !important;
      border: none !important;
      padding: 0 !important;
    }
    .vc-design-locket .vc-play-btn {
      width: 32px !important;
      height: 32px !important;
      background: radial-gradient(circle at 35% 30%, #C9A961, #826417) !important;
      box-shadow:
        0 1px 3px rgba(40,25,5,0.40),
        inset 0 1px 1px rgba(255,235,170,0.30) !important;
    }
    .vc-design-locket .vc-play-icon { fill: #2A1A05 !important; width: 12px !important; height: 12px !important; }
    .vc-design-locket .vc-wave-bar {
      background: linear-gradient(180deg, #826417, #5A4410) !important;
      width: 1.5px !important;
    }
    .vc-design-locket .vc-wave-bar:nth-child(2n) { display: none !important; }
    .vc-design-locket .vc-audio-bottom-row { display: none !important; }
    .vc-design-locket .vc-imprint {
      border-top: none !important;
      padding-top: 4px !important;
    }
    .vc-design-locket .vc-imprint-primary {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-size: 9px !important;
      font-style: italic !important;
      color: rgba(90,68,16,0.65) !important;
      letter-spacing: 0.04em !important;
    }
    .vc-design-locket .vc-imprint-secondary {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-size: 8px !important;
      font-style: italic !important;
      color: rgba(90,68,16,0.45) !important;
      margin-top: 1px !important;
    }
    .vc-design-locket .vc-imprint-time { display: none !important; }
    .vc-design-locket .vc-imprint-divider { display: none !important; }
    .vc-design-locket .vc-serial-default { display: none !important; }
    .vc-design-locket .vc-serial-tag {
      display: inline !important;
      color: rgba(90,68,16,0.45) !important;
    }


    /* ════════════════════════════════════════════════════════════
       VOICECARD DESIGN — THE TELEGRAM
       FORM: WIDE horizontal strip (3 × 2 ratio) with perforated top
       and bottom edges. Kraft paper. Mono uppercase type. Reads as a
       wired teletype message — urgent, mechanical, brief.
       ──────────────────────────────────────────────────────────── */
    .vc-card-frame.vc-design-telegram {
      background: linear-gradient(178deg, #F0E6CD 0%, #DCCFA8 100%) !important;
      aspect-ratio: 3 / 2 !important;
      max-width: 360px !important;
      padding: 0 !important;
      border-radius: 0 !important;
      -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 360 240' preserveAspectRatio='none'%3E%3Cpath d='M0 5 L8 0 L16 5 L24 0 L32 5 L40 0 L48 5 L56 0 L64 5 L72 0 L80 5 L88 0 L96 5 L104 0 L112 5 L120 0 L128 5 L136 0 L144 5 L152 0 L160 5 L168 0 L176 5 L184 0 L192 5 L200 0 L208 5 L216 0 L224 5 L232 0 L240 5 L248 0 L256 5 L264 0 L272 5 L280 0 L288 5 L296 0 L304 5 L312 0 L320 5 L328 0 L336 5 L344 0 L352 5 L360 0 L360 235 L352 240 L344 235 L336 240 L328 235 L320 240 L312 235 L304 240 L296 235 L288 240 L280 235 L272 240 L264 235 L256 240 L248 235 L240 240 L232 235 L224 240 L216 235 L208 240 L200 235 L192 240 L184 235 L176 240 L168 235 L160 240 L152 235 L144 240 L136 235 L128 240 L120 235 L112 240 L104 235 L96 240 L88 235 L80 240 L72 235 L64 240 L56 235 L48 240 L40 235 L32 240 L24 235 L16 240 L8 235 L0 240 Z' fill='black'/%3E%3C/svg%3E") !important;
              mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 360 240' preserveAspectRatio='none'%3E%3Cpath d='M0 5 L8 0 L16 5 L24 0 L32 5 L40 0 L48 5 L56 0 L64 5 L72 0 L80 5 L88 0 L96 5 L104 0 L112 5 L120 0 L128 5 L136 0 L144 5 L152 0 L160 5 L168 0 L176 5 L184 0 L192 5 L200 0 L208 5 L216 0 L224 5 L232 0 L240 5 L248 0 L256 5 L264 0 L272 5 L280 0 L288 5 L296 0 L304 5 L312 0 L320 5 L328 0 L336 5 L344 0 L352 5 L360 0 L360 235 L352 240 L344 235 L336 240 L328 235 L320 240 L312 235 L304 240 L296 235 L288 240 L280 235 L272 240 L264 235 L256 240 L248 235 L240 240 L232 235 L224 240 L216 235 L208 240 L200 235 L192 240 L184 235 L176 240 L168 235 L160 240 L152 235 L144 240 L136 235 L128 240 L120 235 L112 240 L104 235 L96 240 L88 235 L80 240 L72 235 L64 240 L56 235 L48 240 L40 235 L32 240 L24 235 L16 240 L8 235 L0 240 Z' fill='black'/%3E%3C/svg%3E") !important;
      -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
      box-shadow: 0 4px 12px rgba(60,40,20,0.20) !important;
    }
    .vc-design-telegram .vc-accent-line { display: none !important; }
    .vc-design-telegram .vc-mid-border {
      background: transparent !important;
      padding: 18px 20px !important;
      clip-path: none !important;
      box-shadow: none !important;
    }
    .vc-design-telegram .vc-mid-scallop { display: none !important; }
    .vc-design-telegram #vc-card-color-main {
      background: transparent !important;
    }
    .vc-design-telegram .vc-content {
      padding: 0 !important;
      display: flex !important;
      flex-direction: column;
      height: 100%;
      gap: 4px;
    }
    .vc-design-telegram .vc-title-block {
      margin: 0 0 6px !important;
      text-align: left !important;
    }
    .vc-design-telegram .vc-title-block > div:first-child {
      font-family: 'Courier New', 'Courier', monospace !important;
      font-size: 13px !important;
      font-weight: 700 !important;
      font-style: normal !important;
      letter-spacing: 0.10em !important;
      text-transform: uppercase !important;
      color: #2A1A0A !important;
      text-align: left !important;
      text-shadow: none !important;
      min-height: 16px !important;
    }
    .vc-design-telegram .vc-title-rule {
      background: #2A1A0A !important;
      width: 100% !important;
      height: 1px !important;
      margin: 4px 0 0 !important;
    }
    .vc-design-telegram .vc-sender-section {
      gap: 10px !important;
      margin: 4px 0 6px !important;
      justify-content: flex-start !important;
    }
    /* Photo as a proper passport-ID box inside the telegram strip —
       the wide 360px aspect leaves huge horizontal slack, so this box
       grows from 32×40 to 60×76. The dashed border reads as the
       cut-out frame on a real telegraphic ID slip. */
    .vc-design-telegram .vc-photo-frame {
      width: 60px !important;
      height: 76px !important;
      border-radius: 0 !important;
      background: #E0D5B0 !important;
      border: 1px dashed rgba(40,25,10,0.55) !important;
      box-shadow: inset 0 0 0 2px rgba(240,230,205,0.85), inset 0 0 0 3px rgba(40,25,10,0.30) !important;
    }
    /* Re-balance: align sender info to centre on the larger photo */
    .vc-design-telegram .vc-sender-section {
      align-items: center !important;
    }
    .vc-design-telegram .vc-sender-info {
      flex: 1 1 auto !important;
    }
    .vc-design-telegram .vc-sender-info { text-align: left !important; }
    .vc-design-telegram .vc-from-caption {
      font-family: 'Courier New', monospace !important;
      font-size: 8px !important;
      font-weight: 700 !important;
      letter-spacing: 0.20em !important;
      color: rgba(40,25,10,0.55) !important;
      text-shadow: none !important;
    }
    .vc-design-telegram .vc-sender-name {
      font-family: 'Courier New', monospace !important;
      font-size: 14px !important;
      font-weight: 700 !important;
      font-style: normal !important;
      text-transform: uppercase !important;
      letter-spacing: 0.04em !important;
      color: #2A1A0A !important;
      text-shadow: none !important;
    }
    .vc-design-telegram .vc-audio-block { margin: 6px 0 !important; }
    .vc-design-telegram .vc-audio-panel {
      background: transparent !important;
      border: none !important;
      padding: 0 !important;
      border-radius: 0 !important;
    }
    .vc-design-telegram .vc-play-btn {
      width: 32px !important;
      height: 32px !important;
      background: #2A1A0A !important;
      border-radius: 0 !important;
      box-shadow: none !important;
    }
    .vc-design-telegram .vc-play-icon { fill: #F0E6CD !important; width: 14px !important; height: 14px !important; }
    .vc-design-telegram .vc-wave-bar {
      background: #2A1A0A !important;
      width: 1.5px !important;
      border-radius: 0 !important;
    }
    .vc-design-telegram .vc-audio-bottom-row { display: none !important; }
    .vc-design-telegram .vc-imprint {
      border-top: 1px solid #2A1A0A !important;
      padding-top: 6px !important;
      margin-top: auto !important;
      text-align: left !important;
    }
    .vc-design-telegram .vc-imprint-primary,
    .vc-design-telegram .vc-imprint-secondary {
      font-family: 'Courier New', monospace !important;
      font-size: 9px !important;
      font-weight: 700 !important;
      font-style: normal !important;
      text-transform: uppercase !important;
      letter-spacing: 0.10em !important;
      color: rgba(40,25,10,0.75) !important;
      text-shadow: none !important;
      text-align: left !important;
    }
    .vc-design-telegram .vc-imprint-date::before {
      content: "RECEIVED ";
      color: rgba(40,25,10,0.50);
    }
    .vc-design-telegram .vc-imprint-time::before {
      content: "SENT ";
      color: rgba(40,25,10,0.50);
    }
    .vc-design-telegram .vc-serial-default { display: none !important; }
    .vc-design-telegram .vc-serial-ref {
      display: inline !important;
      color: rgba(40,25,10,0.55) !important;
    }

    /* Pressed card edge - museum-grade stationery feel */
    .occasion-type-btn:active {
      box-shadow: 0 1px 0 rgba(255,255,255,0.4), 0 1px 3px rgba(0,0,0,0.1) !important;
    }
    
    /* ════════════════════════════════════════════════════════════
       PETRA TYPOGRAPHIC SYSTEM
       One small, disciplined toolkit applied across every screen.
       ──────────────────────────────────────────────────────────
       Tracking values — there are five, no more:
         --track-tight   for display titles (Cormorant 600+)
         --track-text    for body
         --track-italic  for italic body (italic needs slight loosening)
         --track-sc      for serif small-caps editorial labels
         --track-label   for sans uppercase UI chrome
       Cormorant Garamond gets old-style figures + ligatures globally;
       tabular figures are a separate utility for counters.
       ════════════════════════════════════════════════════════════ */
    :root {
      --track-tight:  -0.01em;
      --track-text:    0;
      --track-italic:  0.005em;
      --track-sc:      0.04em;
      --track-label:   0.16em;
    }
    /* Cormorant Garamond — wherever it appears, give it the proper
       text features: old-style numerals for narrative figures, common
       and discretionary ligatures for the typeface's full character. */
    body { font-feature-settings: "kern" 1; }
    [style*="Cormorant Garamond"],
    [class*="lt-"] [style*="serif"] {
      font-feature-settings: "onum" 1, "liga" 1, "dlig" 1, "kern" 1;
    }
    /* A simple selector that catches every Cormorant Garamond
       container by font-family attribute is unreliable in practice;
       use a utility class for explicit application. */
    .pt-osf { font-feature-settings: "onum" 1, "liga" 1, "dlig" 1, "kern" 1; }
    /* Tabular figures for counters / durations / prices — fixed-width
       numerals so they line up vertically in lists. */
    .pt-tnum { font-feature-settings: "tnum" 1, "lnum" 1; font-variant-numeric: tabular-nums; }
    /* Beautiful ampersand — Cormorant italic ampersand wherever an
       ampersand appears, even in sans contexts. The single most
       valuable typographic flourish you can install in a serif app. */
    .amp {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-style: italic;
      font-weight: 500;
      font-feature-settings: "liga" 1, "dlig" 1;
    }
    /* Petra wordmark — ONE treatment, applied wherever the brand name
       is set as a mark (auth screen, post-office trim, footers).
       Small caps with a hint of negative tracking so the letters seat
       together as one drawn unit. */
    .petra-wordmark {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-weight: 600;
      font-style: italic;
      font-variant: small-caps;
      letter-spacing: var(--track-tight);
      font-feature-settings: "smcp" 1, "liga" 1, "dlig" 1, "kern" 1;
    }
    /* Editorial small-caps labels — for content tags ("From," "Date,")
       not UI chrome. Pair with Cormorant. */
    .pt-sc {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-variant: small-caps;
      font-feature-settings: "smcp" 1, "kern" 1;
      letter-spacing: var(--track-sc);
    }
    /* UI chrome label — tracked sans uppercase, the existing house
       voice for utilitarian markers like "DROP CAP", "PAPER", etc. */
    .pt-label {
      font-family: 'DM Sans', sans-serif;
      text-transform: uppercase;
      letter-spacing: var(--track-label);
      font-weight: 600;
      font-size: 10px;
    }
    /* Typographic ornaments — fleurons / dingbats. Use sparingly; one
       per moment. Earn the mark. */
    .pt-fleuron {
      display: inline-block;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-style: italic;
      color: rgba(120,90,50,0.40);
      letter-spacing: 0.4em;
    }

    /* Screen transitions - settle into place, don't snap */
    /* Use ID-level specificity via body prefix to beat Tailwind CDN classes */
    body .screen {
      display: none;
      position: fixed;
      top: 0; left: 0; right: 0; bottom: 0;
      z-index: 1;
      background: var(--petra-cream, #F4EFE7);
    }
    body .screen.active { 
      display: flex; 
      flex-direction: column; 
      height: 100vh;
      height: 100dvh;
      overflow: hidden;
      z-index: 2;
    }
    
    /* Album delete — visible on hover/long-press */
    button:hover .album-delete-btn,
    button:active .album-delete-btn {
      opacity: 1 !important;
    }
    
    /* Main content area must have explicit constraints for scroll to work */
    .screen.active > main {
      flex: 1 1 0%;
/* min-height inherited from .kp-card base */
      overflow-y: auto;
      -webkit-overflow-scrolling: touch;
    }
    
    /* Scrollable areas - natural momentum */
    .overflow-y-auto,
    .overflow-auto {
      -webkit-overflow-scrolling: touch;
    }
    
    /* Scrollbar styling - minimal, unobtrusive */
    ::-webkit-scrollbar {
      width: 4px;
      height: 4px;
    }
    ::-webkit-scrollbar-track {
      background: transparent;
    }
    ::-webkit-scrollbar-thumb {
      background: rgba(139, 115, 85, 0.2);
      border-radius: 4px;
    }
    ::-webkit-scrollbar-thumb:hover {
      background: rgba(139, 115, 85, 0.35);
    }
    
    /* Hidden scrollbar utility for horizontal scroll rails */
    .no-scrollbar {
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    .no-scrollbar::-webkit-scrollbar {
      display: none;
      width: 0;
      height: 0;
    }
    
    /* Stamp category tab tap feedback */
    .stamp-cat-tab:active {
      transform: scale(0.96);
    }
    
    /* Home screen - allow scrolling for journal section */
    #home-screen {
      overflow-y: auto !important;
      overflow-x: hidden !important;
      overscroll-behavior: none;
      -webkit-overflow-scrolling: touch;
    }
    #home-screen.active {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      height: 100vh;
      height: 100dvh;
      max-height: 100vh;
      max-height: 100dvh;
    }
    
    /* Interactive cards - gentle lift, not hover state */
    .interactive-card {
      transition: transform 0.2s var(--ease-settle),
                  box-shadow 0.2s var(--ease-settle);
    }
    .interactive-card:hover {
      transform: translateY(-1px);
    }
    .interactive-card:active {
      transform: translateY(0) scale(0.99);
    }
    
    /* Modal overlays - fade in gently */
    .modal-overlay {
      transition: opacity 0.2s var(--ease-gentle);
    }
    .modal-overlay.hidden {
      opacity: 0;
      pointer-events: none;
    }
    
    /* Form elements - comfortable interaction */
    input[type="text"],
    input[type="email"],
    input[type="url"],
    textarea {
      transition: box-shadow 0.15s var(--ease-gentle),
                  border-color 0.15s var(--ease-gentle);
    }
    input[type="text"]:focus,
    input[type="email"]:focus,
    input[type="url"]:focus,
    textarea:focus {
      outline: none;
      box-shadow: 0 0 0 2px rgba(196, 164, 132, 0.3);
    }
    
    /* Success states - calm confirmation, not celebration */
    .state-success {
      animation: gentleConfirm 0.4s var(--ease-settle);
    }
    @keyframes gentleConfirm {
      0% { transform: scale(0.95); opacity: 0; }
      100% { transform: scale(1); opacity: 1; }
    }
    
    /* Error states - gentle attention, not alarm */
    .state-error {
      animation: gentleAttention 0.3s var(--ease-gentle);
    }
    @keyframes gentleAttention {
      0%, 100% { transform: translateX(0); }
      25% { transform: translateX(-3px); }
      75% { transform: translateX(3px); }
    }
    
    /* ═══════ MESSAGES TO SELF — Journal & Time Capsule ═══════ */
    @keyframes journalCardEntrance {
      0% { opacity: 0; transform: translateY(8px) scale(0.97); }
      100% { opacity: 1; transform: translateY(0) scale(1); }
    }
    @keyframes waxSealDrop {
      0% { transform: scale(1.25) translateY(-12px); opacity: 0; }
      45% { transform: scale(0.95) translateY(2px); opacity: 1; }
      65% { transform: scale(1.04) translateY(-1px); }
      80% { transform: scale(0.99) translateY(0.5px); }
      100% { transform: scale(1) translateY(0); opacity: 1; }
    }
    @keyframes sealTextFade {
      0% { opacity: 0; transform: translateY(6px); }
      100% { opacity: 1; transform: translateY(0); }
    }
    @keyframes journalKeptPulse {
      0% { transform: scale(1); }
      50% { transform: scale(0.97); }
      100% { transform: scale(1); }
    }
    .journal-card-surface {
      transition: transform 0.25s var(--ease-settle), box-shadow 0.25s var(--ease-settle);
      cursor: pointer;
    }
    .journal-card-surface:hover { transform: scale(1.02); }
    .journal-card-surface:active { transform: scale(0.98); }
    
    /* ═══════ HOME SCREEN ENTRANCE ANIMATIONS ═══════ */
    /* Keepsake philosophy: everything arrives like a treasured letter —
       gently, with weight and presence, as if being placed on a desk */
    
    @keyframes ks-title-unveil {
      0% { opacity: 0; transform: translateY(-12px); filter: blur(4px); }
      60% { opacity: 1; filter: blur(0); }
      100% { opacity: 1; transform: translateY(0); filter: blur(0); }
    }
    
    @keyframes ks-subtitle-ink {
      0% { opacity: 0; clip-path: inset(0 100% 0 0); }
      100% { opacity: 1; clip-path: inset(0 0% 0 0); }
    }

    @keyframes ks-quickstart-fade {
      0%   { opacity: 0; transform: translateY(4px); }
      100% { opacity: 1; transform: translateY(0); }
    }

    .ks-quickstart-chip:hover {
      transform: translateY(-1px);
      filter: brightness(1.04);
    }
    .ks-quickstart-chip:active {
      transform: translateY(0) scale(0.985);
    }
    
    @keyframes ks-section-label-fade {
      0% { opacity: 0; letter-spacing: 0.2em; }
      100% { opacity: 1; letter-spacing: 0.05em; }
    }
    
    @keyframes ks-card-place {
      0% { opacity: 0; transform: translateY(20px) rotate(-1.5deg) scale(0.92); }
      50% { opacity: 1; transform: translateY(-3px) rotate(0.3deg) scale(1.01); }
      75% { transform: translateY(1px) rotate(-0.1deg) scale(0.998); }
      100% { opacity: 1; transform: translateY(0) rotate(0) scale(1); }
    }
    
    @keyframes ks-card-place-alt {
      0% { opacity: 0; transform: translateY(20px) rotate(1.5deg) scale(0.92); }
      50% { opacity: 1; transform: translateY(-3px) rotate(-0.3deg) scale(1.01); }
      75% { transform: translateY(1px) rotate(0.1deg) scale(0.998); }
      100% { opacity: 1; transform: translateY(0) rotate(0) scale(1); }
    }
    
    @keyframes ks-rule-draw {
      0% { transform: scaleX(0); opacity: 0; }
      100% { transform: scaleX(1); opacity: 1; }
    }
    
    @keyframes ks-stat-emerge {
      0% { opacity: 0; transform: scale(0.5); }
      60% { transform: scale(1.08); }
      80% { transform: scale(0.96); }
      100% { opacity: 1; transform: scale(1); }
    }
    
    @keyframes ks-stat-diamond-emerge {
      0% { opacity: 0; transform: rotate(45deg) scale(0.5); }
      60% { transform: rotate(45deg) scale(1.08); }
      80% { transform: rotate(45deg) scale(0.96); }
      100% { opacity: 1; transform: rotate(45deg) scale(1); }
    }
    
    @keyframes ks-nav-rise {
      0% { opacity: 0; transform: translateY(100%); }
      100% { opacity: 1; transform: translateY(0); }
    }
    
    @keyframes ks-header-btn-appear {
      0% { opacity: 0; transform: scale(0.7); }
      70% { transform: scale(1.05); }
      100% { opacity: 1; transform: scale(1); }
    }
    
    @keyframes ks-gentle-breathe {
      0%, 100% { box-shadow: 0 1px 0 rgba(180,160,130,0.35), 0 2px 4px rgba(80,60,40,0.12), 0 6px 12px rgba(60,40,20,0.08); }
      50% { box-shadow: 0 1px 0 rgba(180,160,130,0.35), 0 3px 8px rgba(80,60,40,0.16), 0 8px 16px rgba(60,40,20,0.1); }
    }
    
    /* Idle shimmer for stats — like light catching a keepsake */
    @keyframes ks-shimmer-catch {
      0%, 100% { box-shadow: 0 2px 6px rgba(30,58,95,0.3), inset 0 1px 0 rgba(255,255,255,0.12); }
      50% { box-shadow: 0 2px 8px rgba(30,58,95,0.4), inset 0 1px 0 rgba(255,255,255,0.25); }
    }
    
    @keyframes ks-dictate-pulse {
      0%, 100% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.4); opacity: 0.6; }
    }
    
    @keyframes ks-page-shrink-fly {
      0% { transform: scale(1) translateY(0) rotate(0deg); opacity: 1; }
      30% { transform: scale(0.85) translateY(-20px) rotate(-1deg); opacity: 1; }
      70% { transform: scale(0.35) translateY(120px) rotate(-2deg); opacity: 0.9; }
      100% { transform: scale(0.2) translateY(200px) rotate(-3deg); opacity: 0; }
    }
    
    @keyframes ks-book-emerge {
      0% { opacity: 0; transform: translateX(-50%) scale(0.7) translateY(40px); }
      60% { opacity: 1; transform: translateX(-50%) scale(1.05) translateY(-5px); }
      100% { opacity: 1; transform: translateX(-50%) scale(1) translateY(0); }
    }
    
    @keyframes ks-gold-shimmer {
      0% { opacity: 0; }
      30% { opacity: 1; }
      100% { opacity: 0; }
    }
    
    @keyframes ks-preserved-text {
      0% { opacity: 0; transform: translateY(10px); letter-spacing: 0.3em; }
      100% { opacity: 1; transform: translateY(0); letter-spacing: 0.15em; }
    }
    
    /* Class applied during entrance */
    .ks-animating .journal-card-surface {
      will-change: transform, opacity;
    }
    .journal-textarea {
      border: none; outline: none; resize: none; width: 100%;
      min-height: 100px; background: transparent;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-style: italic; font-size: 16px; line-height: 1.75;
      color: #3a342c; caret-color: #8B7355;
    }
    .journal-textarea::placeholder { color: #b8b0a4; font-style: italic; }
    .journal-textarea:focus { box-shadow: none; }
    .capsule-pill {
      display: inline-flex; align-items: center; justify-content: center;
      padding: 8px 18px; border-radius: 20px;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 13px; font-weight: 600; letter-spacing: 0.04em;
      cursor: pointer; transition: all 0.2s var(--ease-settle);
      border: 1px solid #d4cec4; background: #FAF8F3; color: #6a6258;
    }
    .capsule-pill:hover { background: #f0ebe3; }
    .capsule-pill.selected {
      background: #4a5868; color: #f0ebe3; border-color: #4a5868;
      box-shadow: 0 2px 8px rgba(74,88,104,0.25);
    }
    .wax-seal-overlay {
      position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
      background: rgba(74,88,104,0.12); border-radius: 5px; backdrop-filter: blur(1px);
    }
    .journal-month-header {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px; font-weight: 600; letter-spacing: 0.14em;
      text-transform: uppercase; color: #8a8278; padding: 16px 0 8px;
    }

    /* Global Navigation Styles - Original leather design */
    /* ═══ KEEPSAKE DRAWER — REMOVED 2026-05-17 ═══
       The compact walnut drawer that lived at the bottom of every screen
       has been removed entirely. Its only meaningful entry point — the
       "Self" tile that led to Personal Keepsakes — is now reached by
       long-pressing the Today icon in the header. (See .today-history-spine
       CSS + the setupTodayLongPress() handler later in this file.) */

    /* ═══ TODAY ICON — HISTORY SPINE ═══
       When the user has saved journal entries, a subtle stacked-pages
       spine peeks out on the right edge of the Today icon. Self-evident
       affordance that history lives here. Long-press the icon to open
       Personal Keepsakes. */
    .today-history-spine {
      position: absolute;
      top: 3px;
      bottom: 3px;
      right: -3px;
      width: 4px;
      pointer-events: none;
      background: linear-gradient(
        to right,
        rgba(180, 150, 110, 0.55) 0%,
        rgba(150, 120, 80, 0.65) 50%,
        rgba(120, 90, 55, 0.75) 100%
      );
      border-radius: 0 3px 3px 0;
      box-shadow: 1px 0 2px rgba(80, 55, 25, 0.25);
      opacity: 0;
      transform: scaleX(0.4);
      transform-origin: left center;
      transition: opacity 0.35s cubic-bezier(0.22, 1, 0.36, 1), transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .today-history-spine::before,
    .today-history-spine::after {
      content: '';
      position: absolute;
      top: 1px; bottom: 1px;
      width: 1px;
      background: rgba(255, 245, 225, 0.35);
    }
    .today-history-spine::before { left: 1px; }
    .today-history-spine::after  { left: 2.5px; }
    .has-history .today-history-spine {
      opacity: 1;
      transform: scaleX(1);
      /* 2026-05-20: promote the spine from decoration to a real Krug-style
         tap target once entries exist. Before this, the only path to
         Personal Keepsakes was a hidden long-press — undiscoverable. Now:
           • Spine is a proper bookmark-tab beside the Today icon
           • cursor:pointer + pointer-events:auto make it tappable
           • Hover/active states confirm "yes this is a button"
           • Long-press on the icon body still works for power users
         The visible chevron is the primary Krug fix; the coach mark
         (.today-spine-coach below) teaches the gesture once on first
         appearance and then never again.
         2026-05-20 (refined): user feedback — 11px tap target was too
         narrow. Bumped to ~28px wide, full icon height, with the chevron
         scaled up so the affordance reads as a real button on mobile. */
      width: 28px;
      right: -24px;
      top: 0;
      bottom: 0;
      pointer-events: auto;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      background: linear-gradient(
        to right,
        rgba(184, 152, 110, 0.85) 0%,
        rgba(160, 128, 86, 0.92) 50%,
        rgba(130, 100, 60, 1) 100%
      );
      border-radius: 0 10px 10px 0;
      box-shadow:
        1px 0 4px rgba(80, 55, 25, 0.30),
        inset 0 1px 0 rgba(255, 235, 200, 0.30),
        inset 0 -1px 0 rgba(60, 35, 10, 0.30);
    }
    .has-history .today-history-spine:hover {
      background: linear-gradient(
        to right,
        rgba(200, 168, 124, 0.92) 0%,
        rgba(172, 140, 96, 0.96) 50%,
        rgba(140, 108, 68, 1) 100%
      );
      box-shadow:
        2px 0 8px rgba(140, 100, 50, 0.50),
        inset 0 1px 0 rgba(255, 240, 210, 0.40),
        inset 0 -1px 0 rgba(60, 35, 10, 0.30);
    }
    .has-history .today-history-spine:active {
      transform: scaleX(1) translateX(1px);
      box-shadow:
        1px 0 3px rgba(80, 55, 25, 0.40),
        inset 0 2px 4px rgba(60, 35, 10, 0.30);
    }
    .today-history-spine:focus-visible {
      outline: 2px solid rgba(255, 230, 180, 0.85);
      outline-offset: 2px;
    }
    /* The thin "page-edge" stripes from the original 4px spine no longer
       fit the wider bookmark tab — hide them when has-history kicks in
       so we don't get awkward decorative lines next to the chevron. */
    .has-history .today-history-spine::before,
    .has-history .today-history-spine::after {
      display: none;
    }
    .today-history-spine .spine-chevron {
      width: 12px;
      height: 16px;
      color: rgba(255, 248, 235, 0.95);
      pointer-events: none;
      filter: drop-shadow(0 1px 1px rgba(60, 35, 10, 0.45));
    }
    /* While the user is holding the icon — the spine subtly glows,
       signalling "something is about to happen." Then a haptic pulse
       fires when the long-press threshold is crossed. */
    .today-pressing .today-history-spine {
      box-shadow: 1px 0 4px rgba(180, 130, 60, 0.55);
    }
    /* First-run coach mark — sits to the right of the Today icon and
       gently tells the user the spine is tappable. Fades in, holds,
       fades out. Saved in localStorage so it only ever fires once. */
    .today-spine-coach {
      position: absolute;
      top: 50%;
      left: calc(100% + 10px);
      transform: translateY(-50%);
      background: rgba(60, 40, 20, 0.92);
      color: #FAF3E5;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px;
      font-style: italic;
      padding: 6px 10px;
      border-radius: 8px;
      white-space: nowrap;
      pointer-events: none;
      z-index: 100;
      box-shadow: 0 3px 12px rgba(0, 0, 0, 0.22);
      animation: spine-coach-pulse 4.5s ease-in-out forwards;
    }
    .today-spine-coach::before {
      content: '';
      position: absolute;
      left: -5px;
      top: 50%;
      transform: translateY(-50%);
      border: 5px solid transparent;
      border-right-color: rgba(60, 40, 20, 0.92);
      border-left: 0;
    }
    @keyframes spine-coach-pulse {
      0%   { opacity: 0; transform: translateY(-50%) translateX(-6px); }
      12%  { opacity: 1; transform: translateY(-50%) translateX(0); }
      82%  { opacity: 1; transform: translateY(-50%) translateX(0); }
      100% { opacity: 0; transform: translateY(-50%) translateX(0); }
    }

    /* ═══ NAV — The Postal Counter ═══
       Bottom edge of every screen is finished as the surface of a
       1920s post-office counter. Mahogany top with visible long
       grain, ink stains, and a single warm pendant light from
       above. On the LEFT: a small brass desk-bell — a hemispherical
       dome with a chrome plunger at top — that rings (single brass
       ting) and returns Home. On the RIGHT: a brass mail-slot with
       "POSTE" engraved above; the flap flips up briefly on tap and
       opens the Album. A small red wax stamp slides between the
       two objects to mark the room you're currently in. ═══ */

    #petra-nav-bar {
      position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
      display: none; padding: 0;
    }

    /* The maroon bookbinder's-cloth backing — the bar's main surface.
       Three-stop vertical gradient (deep wine top → warm-lit centre →
       deepest red-black at bottom) gives the cloth dye real depth-of-
       tone the way a real linen-bound book cover catches light. The
       radial halo at top-centre is the warm pendant-lamp from above. */
    #petra-nav-bar .pc-counter {
      --stamp-flight-duration: 420ms;
      position: relative;
      width: 100%;
      /* 2026-05-26 — Reduced from 90px → 72px. The bell + album use
         percentage-based vertical positioning (top:44% / 50%) so they
         naturally re-center inside the new height with no per-icon
         adjustment needed. Labels + wax-stamp tightened below. */
      height: 72px;
      padding-bottom: env(safe-area-inset-bottom, 0px);
      /* The maroon bookbinder's-cloth backing — three-stop vertical gradient
         (deep wine top → warm-lit centre → deepest red-black bottom) plus a
         warm radial halo at top-centre (the overhead lamp). 2026-06-03 —
         restored the original depth (gradient + glow + upward cast shadow)
         per founder, after the brief flat-uniform experiment. */
      background:
        radial-gradient(ellipse at 50% 0%, rgba(255, 220, 170, 0.10) 0%, transparent 65%),
        linear-gradient(180deg, #5A1A22 0%, #3F1218 55%, #260A0E 100%);
      box-shadow:
        inset 0 1px 0 rgba(255, 220, 180, 0.14),
        inset 0 -1px 0 rgba(0, 0, 0, 0.32),
        0 -4px 14px rgba(0, 0, 0, 0.18),
        0 -1px 0 rgba(0, 0, 0, 0.20);
      overflow: hidden;
    }

    /* Cloth weave — two layered SVGs:
       1. A tight 4 × 4 px crosshatch reading as warp + weft threads of
          the maroon binding-cloth.
       2. A long-wave fractal-noise tonal pass that breaks the regularity
          of the crosshatch and gives the dyed cloth the slight unevenness
          real fabric always has. */
    #petra-nav-bar .pnb-weave {
      position: absolute; inset: 0;
      background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cline x1='0' y1='2' x2='4' y2='2' stroke='%23000' stroke-width='0.55' stroke-opacity='0.20'/%3E%3Cline x1='2' y1='0' x2='2' y2='4' stroke='%23000' stroke-width='0.45' stroke-opacity='0.16'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240'%3E%3Cfilter id='cw1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6 0.10' numOctaves='2' seed='17' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.42 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23cw1)'/%3E%3C/svg%3E");
      background-size: 4px 4px, 240px 240px;
      mix-blend-mode: multiply;
      opacity: 0.55;
      pointer-events: none;
    }

    /* Hand-stitching along the top + bottom edges — repeating short
       dashes in faint linen colour (rgba(220,200,160,0.40)). The cloth
       has been hand-stitched onto the page above (top) and to the
       counter's apron below (bottom). Inset 14 px from the side edges
       so the stitches read as deliberately laid, not auto-generated. */
    #petra-nav-bar .pnb-stitch {
      position: absolute; left: 14px; right: 14px;
      height: 1px;
      background-image: repeating-linear-gradient(90deg,
        rgba(220, 200, 160, 0.42) 0 4px,
        transparent 4px 8px);
      pointer-events: none;
    }
    #petra-nav-bar .pnb-stitch-top { top: 5px; }
    #petra-nav-bar .pnb-stitch-bot {
      bottom: calc(5px + env(safe-area-inset-bottom, 0px));
      opacity: 0.55;
    }

    /* Pendant-light halo — sits ABOVE the weave + noise so the top of
       the cloth reads as catching warm light from a single overhead
       lamp, not just gradient-coloured. */
    #petra-nav-bar .pc-light {
      position: absolute; left: 0; right: 0; top: 0;
      height: 65%;
      background: radial-gradient(ellipse at 50% -20%, rgba(255, 220, 170, 0.10) 0%, transparent 70%);
      pointer-events: none;
      mix-blend-mode: screen;
    }

    /* The active-state wax stamp — a small red wax dot that slides
       between the bell and the slot to mark which room you're in.
       Position controlled by a CSS variable on .pc-counter that
       updates via :has() when one of the buttons is .pnb-active. */
    #petra-nav-bar .pc-counter {
      --stamp-x: 22%;  /* default — beside the bell */
    }
    #petra-nav-bar .pc-counter:has(#pnb-album.pnb-active) {
      --stamp-x: 78%;  /* beside the slot */
    }
    /* Nav labels removed 2026-05-27 — the brass bell and leather
       mail slot read clearly enough as Home / Album on their own.
       Less text, more object. */

    #petra-nav-bar .pc-wax-stamp {
      position: absolute;
      bottom: calc(5px + env(safe-area-inset-bottom, 0px));
      left: var(--stamp-x);
      transform: translateX(-50%);
      width: 12px; height: 12px;
      border-radius: 50%;
      background: radial-gradient(circle at 32% 26%, #DC5050 0%, #9B1F1F 55%, #5A0E10 100%);
      box-shadow:
        0 1px 2px rgba(80, 20, 20, 0.40),
        inset 0 1px 0 rgba(255, 200, 180, 0.22),
        inset 0 -1px 0 rgba(0, 0, 0, 0.22);
      transition: left var(--stamp-flight-duration, 420ms) cubic-bezier(0.4, 0, 0.2, 1);
      pointer-events: none;
      z-index: 4;
      will-change: left, transform;
    }

    @media (prefers-reduced-motion: reduce) {
      #petra-nav-bar .pc-wax-stamp {
        transition-duration: 0.01ms;
      }
    }

    /* The brass desk-bell button (LEFT — Home) ───────────────────
       The bell SVG is bottom-weighted inside its 60×50 viewBox (the
       dome + base sit in the lower 70 %), so positioning the button
       at top:50% makes the bell visually sit ~3 px low compared with
       the slot. We compensate by anchoring the button at top:44% so
       the bell's optical centre (around y=28 in the SVG) aligns with
       the bar's vertical centre — matching the slot's eye-line. */
    #petra-nav-bar .pc-bell {
      position: absolute;
      left: 14%; top: 44%;
      transform: translate(-50%, -50%);
      width: 60px; height: 50px;
      background: transparent; border: none; cursor: pointer; padding: 0;
      z-index: 3;
      filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.45));
      transition: transform 0.12s ease, filter 0.18s ease;
    }
    #petra-nav-bar .pc-bell svg {
      display: block; width: 100%; height: 100%;
    }
    #petra-nav-bar .pc-bell:hover {
      filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.50));
    }
    #petra-nav-bar .pc-bell:active,
    #petra-nav-bar .pc-bell.pc-bell-ringing {
      /* Same translate-x as idle (-50%) but a 1 px downward press,
         consistent with the new 44% top anchor. */
      transform: translate(-50%, calc(-50% + 1px)) scale(0.985);
      filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.50));
    }
    /* When ringing: the chrome plunger compresses ~1 px (handled via
       a CSS class that scales the plunger in the SVG) */
    #petra-nav-bar .pc-bell.pc-bell-ringing .pc-plunger {
      transform: translateY(0.6px) scale(0.92);
    }
    #petra-nav-bar .pc-plunger {
      transform-origin: 30px 22px;
      transition: transform 0.10s ease;
    }

    /* The brass mail-slot button (RIGHT — Album) ─────────────────── */
    #petra-nav-bar .pc-mail-slot {
      position: absolute;
      right: 14%; top: 50%;
      transform: translate(50%, -50%);
      width: 80px; height: 50px;
      background: transparent; border: none; cursor: pointer; padding: 0;
      z-index: 3;
      perspective: 220px;
      filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.40));
    }
    #petra-nav-bar .pc-mail-slot svg.pc-slot-svg {
      display: block; width: 100%; height: 100%;
    }
    #petra-nav-bar .pc-mail-slot:hover {
      filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.46));
    }

    /* ═══ ALBUM FRONT COVER — HTML overlay ═══
       Sits over the open-spread SVG, hinged on the spine (left edge).
       Cognac leather, slightly darker at the spine gutter, with a
       subtle inner grain, a soft diagonal sheen, a centered wax seal,
       and a thin silk bookmark peeking out the top. Swings open via
       rotateY on tap to reveal the spread underneath.

       Geometry: the album body in the SVG spans x=12 to x=59 of 80.
       The spine occupies x=12-19 (always visible). The cover overlays
       x=19-59 of 80 → left 23.75%, right 26.25%. Vertically, body
       spans y=6 to y=39 of 50 → top 12%, height 66%. */
    #petra-nav-bar .pc-flap {
      position: absolute;
      left: 23.75%; right: 26.25%;
      top: 12%; height: 66%;
      transform-origin: left center;
      transform: rotateY(0deg);
      transition: transform 0.50s cubic-bezier(0.34, 1.56, 0.64, 1);
      background: linear-gradient(180deg,
        #B8825A 0%,
        #8B5A38 45%,
        #6B3F26 80%,
        #482814 100%);
      /* Slight book-corner softness on the free edge (right), almost
         flush at the spine (left). */
      border-radius: 0.5px 2px 2px 0.5px;
      box-shadow:
        /* spine gutter shadow on the left (hinge edge) — sells the bind */
        inset 2.5px 0 2px rgba(0, 0, 0, 0.58),
        /* fore-edge highlight on the right (free edge) */
        inset -0.5px 0 0 rgba(255, 215, 170, 0.22),
        /* top + bottom rolled edge definition */
        inset 0 0.5px 0 rgba(255, 215, 170, 0.30),
        inset 0 -0.5px 0 rgba(0, 0, 0, 0.45),
        /* cover sitting above pages */
        0 1px 2px rgba(0, 0, 0, 0.42);
      pointer-events: none;
      backface-visibility: hidden;
      -webkit-backface-visibility: hidden;
    }

    /* Leather grain — soft radial mottling that reads as "used leather,
       not plastic." Two opposed pools to avoid feeling symmetrical. */
    #petra-nav-bar .pc-flap-grain {
      position: absolute;
      inset: 0;
      background:
        radial-gradient(ellipse 70% 50% at 28% 32%, rgba(255, 215, 170, 0.13), transparent 60%),
        radial-gradient(ellipse 60% 60% at 78% 72%, rgba(0, 0, 0, 0.22), transparent 55%);
      border-radius: inherit;
      pointer-events: none;
    }

    /* Soft diagonal sheen — light catching the leather like the bell's
       polished brass. Subtle; this is well-loved leather, not lacquered. */
    #petra-nav-bar .pc-flap-sheen {
      position: absolute;
      inset: 0;
      background: linear-gradient(125deg,
        transparent 30%,
        rgba(255, 235, 195, 0.16) 50%,
        transparent 70%);
      border-radius: inherit;
      pointer-events: none;
    }

    /* Centered wax seal — Petra's signature mark, embossed on the
       cover. Same red-wax vocabulary as the .pc-wax-stamp counter
       dot, slightly larger and with a tiny pressed star inside. */
    #petra-nav-bar .pc-flap-wax {
      position: absolute;
      left: 50%; top: 50%;
      width: 11px; height: 11px;
      border-radius: 50%;
      background: radial-gradient(circle at 32% 26%, #DC5050 0%, #9B1F1F 55%, #5A0E10 100%);
      transform: translate(-50%, -50%);
      box-shadow:
        0 1px 1.5px rgba(60, 12, 12, 0.60),
        inset 0 0.5px 0 rgba(255, 200, 180, 0.34),
        inset 0 -0.5px 0 rgba(0, 0, 0, 0.38);
      pointer-events: none;
    }

    /* Tiny embossed star inside the wax seal — the Petra mark.
       Rendered as a clipped shadow so it reads as PRESSED INTO wax
       (sunken), not painted on. */
    #petra-nav-bar .pc-flap-wax-star {
      position: absolute;
      left: 50%; top: 50%;
      width: 5px; height: 5px;
      transform: translate(-50%, -50%);
      background: linear-gradient(180deg,
        rgba(40, 6, 6, 0.55) 0%,
        rgba(80, 14, 14, 0.30) 100%);
      clip-path: polygon(
        50% 0%, 61% 35%, 98% 35%,
        68% 57%, 79% 91%, 50% 70%,
        21% 91%, 32% 57%, 2% 35%, 39% 35%
      );
      pointer-events: none;
    }

    /* Silk ribbon bookmark — a thin red ribbon peeking out the top of
       the cover, the kind sewn into the spine of a fine photo album.
       Positioned near the spine side (where real ribbons attach). */
    #petra-nav-bar .pc-flap-ribbon {
      position: absolute;
      top: -3px;
      left: 18%;
      width: 3px;
      height: 8px;
      background: linear-gradient(180deg,
        #C8252A 0%,
        #9B1818 50%,
        #6B0E10 100%);
      box-shadow:
        inset 0.5px 0 0 rgba(255, 180, 180, 0.32),
        inset -0.5px 0 0 rgba(0, 0, 0, 0.30),
        0 1px 1px rgba(60, 8, 10, 0.45);
      /* Forked tail */
      clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 72%, 0 100%);
      pointer-events: none;
    }

    /* COVER OPEN — book-style. The cover swings open from the spine
       (left edge), revealing the page spread + photo + handwriting
       in the SVG behind. */
    #petra-nav-bar .pc-mail-slot.pc-flap-open .pc-flap {
      transform: rotateY(-78deg);
    }

    /* ═══ Disclosure summary — suppress default marker ═══
       Used in the contacts sync sheet's "Other ways" link so it
       reads as plain italic text, not a triangle-bullet. */
    #contacts-sync-other-ways summary::-webkit-details-marker { display: none; }
    #contacts-sync-other-ways summary::marker { display: none; content: ''; }

    /* No old chrome from previous nav iterations.
       2026-05-23: `.pnb-label { display:none }` removed — that class
       is now in active use for the HOME / ALBUM specimen labels above
       the bell + album icons. Other dead-class hides kept. */
    .pnb-shape { display: none; }
    /* Hide leftover plaque-specific elements (no longer used; the bell + slot
       sit directly on the cloth instead of inside plaques). */
    .pnb-cloth, .pnb-plaque-grain, .pnb-plaque-scuff, .pnb-plaque-type { display: none; }

    #callcards-screen > main {
      padding-bottom: calc(132px + env(safe-area-inset-bottom, 0px)) !important;
      scroll-padding-bottom: calc(148px + env(safe-area-inset-bottom, 0px));
    }
    .voicecard-review-actions {
      scroll-margin-bottom: calc(148px + env(safe-area-inset-bottom, 0px));
    }

    /* ═══ VoiceCard phonograph (2026-05-20) ═══
       Edison-style wax-cylinder face. Rotation animates the inner wax
       group (.vc-wax-rotor) only — the brass collar, crest, and stylus
       arm stay still — to imply voice being pressed into wax during
       recording and being traced back during playback. The brass
       nameplate carries an "engraved" timer. */
    .vc-phonograph {
      position: relative;
    }
    .vc-phonograph .vc-wax-rotor {
      transform-origin: 100px 100px;
      transition: transform 0.4s ease;
    }
    .vc-phonograph--rotating .vc-wax-rotor {
      animation: vc-wax-spin 6s linear infinite;
    }
    .vc-phonograph--review.vc-phonograph--playing .vc-wax-rotor {
      animation: vc-wax-spin 8s linear infinite;
    }
    @keyframes vc-wax-spin {
      from { transform: rotate(0deg); }
      to   { transform: rotate(360deg); }
    }
    @keyframes vc-pulse {
      0%, 100% { opacity: 1; transform: scale(1); }
      50%      { opacity: 0.45; transform: scale(0.92); }
    }
    .vc-phonograph button:active svg:first-child {
      filter: drop-shadow(0 4px 10px rgba(60,30,15,0.30)) drop-shadow(0 1px 2px rgba(60,30,15,0.18)) brightness(0.96) !important;
    }

    /* Brass nameplate — engraved-look surface for sub-labels + timer.
       Subtle warm gradient + thin dark ruling above and below
       suggests a small brass plaque pressed onto the keepsake. */
    .vc-nameplate {
      display: inline-block;
      padding: 9px 22px;
      background: linear-gradient(180deg, #E2C896 0%, #C8A36A 45%, #A07E40 100%);
      border-radius: 4px;
      box-shadow:
        inset 0 1px 0 rgba(255, 240, 200, 0.55),
        inset 0 -1px 0 rgba(60, 35, 10, 0.30),
        0 2px 6px rgba(80, 50, 20, 0.22);
      border-top: 1px solid rgba(60, 35, 10, 0.30);
      border-bottom: 1px solid rgba(60, 35, 10, 0.30);
      line-height: 1;
    }
    .vc-nameplate--engraved {
      padding: 12px 26px;
      background: linear-gradient(180deg, #EAD0A0 0%, #C8A06E 50%, #8E6E40 100%);
    }
    
    /* Navigation buttons - generous targets, gentle feedback */
    .nav-btn {
      min-width: 40px;
      min-height: 40px;
      transition: transform 0.15s var(--ease-gentle);
    }
    .nav-btn:active {
      transform: scale(0.95);
    }
    .nav-btn-circle {
      transition: transform 0.2s var(--ease-settle),
                  box-shadow 0.2s var(--ease-settle);
    }
      transition: opacity 0.2s ease;
    }
    
    button { cursor: pointer; border: none; background: none; }
    input, textarea { font-family: inherit; }
    
    .category-btn.selected { background: #292524 !important; color: white !important; }
    .template-btn.selected { ring: 4px solid #292524; transform: scale(1.02); }
    .stamp-btn.selected { box-shadow: 0 0 0 2px #292524; }
    .ticket-btn.selected { box-shadow: 0 0 0 2px #292524; }
    .sticker-btn.selected { box-shadow: 0 0 0 2px #292524; }
    .patch-btn.selected { box-shadow: 0 0 0 2px #292524; }
    .seal-btn.selected { box-shadow: 0 0 0 2px #292524; }
    /* Delete button on postcard addons */
    .addon-delete-btn {
      position: absolute; top: -6px; right: -6px; z-index: 20;
      width: 18px; height: 18px; border-radius: 50%;
      background: #c44; color: #fff; border: 1.5px solid #fff;
      font-size: 10px; line-height: 14px; text-align: center;
      cursor: pointer; opacity: 0; transition: opacity 0.2s;
      display: flex; align-items: center; justify-content: center;
      box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    }
    .postcard-addon:hover .addon-delete-btn,
    .postcard-addon:active .addon-delete-btn { opacity: 1; }
    @media (hover: none) { .addon-delete-btn { opacity: 0.8; } }
    .tab-btn.selected { background: #292524 !important; color: white !important; }
    
    /* Leather Album Frame Styles - Handcrafted Keepsake */
    /* Clean container - Aicher-inspired */
    .leather-frame {
      position: relative;
      border-radius: 2px;
      padding: 12px;
      background: #f8f6f3;
      /* Single clean border */
      border: 1px solid #e0ddd8;
    }
    
    /* No decorative elements */
    .leather-frame::before,
    .leather-frame::after {
      display: none;
    }
    
    /* Hide all decorative leather elements */
    .leather-stitch,
    .leather-spine,
    .leather-edge {
      display: none;
    }
    
    /* Inner container - minimal */
    .leather-inner {
      position: relative;
      border-radius: 2px;
      padding: 12px;
      background: transparent;
    }
    
    /* Remove paper texture */
    .leather-inner::before {
      display: none;
    }
    
    /* Category/template buttons - clean transitions */
    .leather-inner .category-btn,
    .leather-inner button {
      transition: transform 0.12s ease, opacity 0.12s ease;
    }
    
    .leather-inner .category-btn:active,
    .leather-inner button:active {
      transform: scale(0.98);
    }
    
    /* ═════════════════════════════════════════════════════════════════
       PETRA ALBUM — Reimagined, Phase A: frame + atmosphere
       Editorial restraint. The page IS the album — no wrapper, no
       leather, no productivity-app tab bar. Cream paper with quiet
       lamplight from above. Letterpress filter chips. Parchment search.
       ═════════════════════════════════════════════════════════════════ */
    .album-atmosphere {
      position: absolute;
      inset: 0;
      pointer-events: none;
      z-index: -1;
      background:
        radial-gradient(ellipse 90% 50% at 50% -8%, rgba(255, 232, 196, 0.16) 0%, transparent 70%),
        radial-gradient(ellipse 70% 40% at 50% 105%, rgba(28, 18, 8, 0.10) 0%, transparent 75%);
    }
    .album-header {
      max-width: 540px;
      margin: 6px auto 22px;
      text-align: center;
    }
    .album-header-count {
      font-family: 'Bodoni Moda', 'Playfair Display', Georgia, serif;
      font-size: 52px;
      font-weight: 500;
      font-style: italic;
      color: #2e2014;
      line-height: 0.95;
      letter-spacing: -0.025em;
      /* Strong letterpress — display type pressed into the paper */
      text-shadow:
        0 1px 0 rgba(255, 250, 240, 0.58),
        0 -0.5px 0 rgba(60, 38, 15, 0.07);
    }
    .album-header-count.album-header-count-empty {
      font-size: 26px;
      font-style: italic;
      color: rgba(80, 55, 30, 0.55);
    }
    .album-header-label {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 13px;
      font-style: italic;
      color: rgba(95, 75, 50, 0.62);
      letter-spacing: 0.03em;
      margin-top: 6px;
      display: block;
      text-shadow: 0 1px 0 rgba(255, 250, 240, 0.50);
    }
    .album-header-since {
      font-family: 'DM Sans', sans-serif;
      font-size: 9.5px;
      font-weight: 500;
      letter-spacing: 0.22em;
      text-transform: uppercase;
      color: rgba(105, 80, 50, 0.42);
      margin-top: 12px;
      display: block;
      text-shadow: 0 0.5px 0 rgba(255, 250, 240, 0.42);
    }
    .album-header-since:empty { display: none; }

    /* Letterpress filter chips — italic Cormorant, ink-stamp underline */
    .album-filter-strip {
      display: flex;
      flex-wrap: wrap;            /* never clip a chip on a narrow phone */
      justify-content: center;
      gap: 9px 18px;             /* row-gap / column-gap (was a flat 28px) */
      max-width: 540px;
      margin: 0 auto 22px;
      padding: 4px 8px;
    }
    @media (max-width: 360px) {
      .album-filter-strip { gap: 8px 13px; }
    }
    /* Post Box (Mail) tabs — letterpress strip identical in language to
       the album filter chips, sized for a 2-tab pair on the inbox
       screen. Switches between Received and Sent views. */
    .postbox-tabs {
      display: flex;
      justify-content: center;
      gap: 28px;
      max-width: 480px;
      margin: 0 auto 16px;
      padding: 2px 0 4px;
    }
    .postbox-tab {
      background: transparent;
      border: none;
      padding: 6px 2px 9px;
      cursor: pointer;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 15.5px;
      font-style: italic;
      color: rgba(90, 70, 45, 0.52);
      letter-spacing: 0.04em;
      position: relative;
      transition: color 0.16s ease, text-shadow 0.16s ease;
      text-shadow: 0 0.5px 0 rgba(255, 250, 240, 0.40);
    }
    .postbox-tab:hover { color: rgba(60, 40, 20, 0.86); }
    .postbox-tab.active {
      color: #2a1810;
      font-weight: 500;
      text-shadow:
        0 1px 0 rgba(255, 250, 240, 0.58),
        0 -0.5px 0 rgba(60, 38, 15, 0.07);
    }
    .postbox-tab.active::after {
      content: '';
      position: absolute;
      left: 50%; bottom: 2px;
      width: 78%; height: 1.5px;
      transform: translateX(-50%);
      background: linear-gradient(90deg,
        rgba(180, 67, 45, 0) 0%,
        rgba(180, 67, 45, 0.85) 18%,
        rgba(180, 67, 45, 0.85) 82%,
        rgba(180, 67, 45, 0) 100%);
    }
    /* Sent panel reuses the album 2-col grid for visual consistency */
    #postbox-sent-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 12px;
      max-width: 32rem; /* matches max-w-lg used in album */
      margin: 0 auto;
    }
    #postbox-sent-empty {
      max-width: 360px;
      margin: 72px auto 40px;
      text-align: center;
      grid-column: 1 / -1;
    }
    #postbox-sent-empty .album-empty-line { /* reuse album empty styling */
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 17px;
      font-style: italic;
      color: rgba(80, 55, 30, 0.55);
      line-height: 1.55;
    }

    .album-filter-chip {
      background: transparent;
      border: none;
      padding: 6px 2px 9px;
      cursor: pointer;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 15.5px;
      font-style: italic;
      color: rgba(90, 70, 45, 0.52);
      letter-spacing: 0.04em;
      position: relative;
      transition: color 0.16s ease, text-shadow 0.16s ease;
      text-shadow: 0 0.5px 0 rgba(255, 250, 240, 0.40);
    }
    .album-filter-chip:hover { color: rgba(60, 40, 20, 0.86); }
    .album-filter-chip.active {
      color: #2a1810;
      font-weight: 500;
      /* Active chip is pressed deeper into the paper */
      text-shadow:
        0 1px 0 rgba(255, 250, 240, 0.58),
        0 -0.5px 0 rgba(60, 38, 15, 0.07);
    }
    /* Ink-stamp underline — letterpress red, soft fade at edges */
    .album-filter-chip.active::after {
      content: '';
      position: absolute;
      left: 50%;
      bottom: 2px;
      width: 78%;
      height: 1.5px;
      background: linear-gradient(90deg,
        rgba(180, 67, 45, 0) 0%,
        rgba(180, 67, 45, 0.85) 18%,
        rgba(180, 67, 45, 0.85) 82%,
        rgba(180, 67, 45, 0) 100%);
      transform: translateX(-50%);
    }

    /* Parchment search slip — no chrome, just a paper strip with a
       quiet underline that brightens to ink-red on focus. */
    .album-search-slip {
      max-width: 480px;
      margin: 0 auto 30px;
      position: relative;
    }
    .album-search-slip input {
      width: 100%;
      padding: 10px 14px 11px 36px;
      border: none;
      border-radius: 3px;
      background:
        linear-gradient(180deg, rgba(255, 252, 244, 0.55) 0%, rgba(245, 238, 224, 0.42) 100%);
      border-bottom: 1px solid rgba(120, 90, 55, 0.22);
      color: #2a1810;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-style: italic;
      font-size: 15px;
      outline: none;
      transition: background 0.18s ease, border-color 0.18s ease;
      box-shadow: 0 1px 2px rgba(60, 40, 20, 0.04);
    }
    .album-search-slip input::placeholder {
      color: rgba(90, 65, 30, 0.42);
      font-style: italic;
    }
    .album-search-slip input:focus {
      background: rgba(255, 252, 244, 0.78);
      border-bottom-color: rgba(180, 67, 45, 0.55);
    }
    .album-search-slip .album-search-icon {
      position: absolute;
      left: 10px;
      top: 50%;
      transform: translateY(-50%);
      color: rgba(120, 90, 55, 0.48);
      pointer-events: none;
    }

    /* Atmospheric empty state */
    .album-empty {
      max-width: 360px;
      margin: 72px auto 40px;
      text-align: center;
      /* Span both columns when dropped into a grid-cols-2 container
         (Favorites empty, search-empty, etc.) so the message reads as
         a centered statement, not a left-stuck cell. */
      grid-column: 1 / -1;
    }
    .album-empty-line {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 17px;
      font-style: italic;
      color: rgba(80, 55, 30, 0.55);
      line-height: 1.55;
      letter-spacing: 0.005em;
    }
    .album-empty-ornament {
      width: 56px;
      height: 18px;
      margin: 18px auto 0;
      opacity: 0.42;
      color: rgba(120, 90, 55, 0.9);
    }
    /* Album empty (true first-run): one gentle next step under the poem. */
    .album-empty-cta {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      margin: 22px auto 0;
      padding: 9px 18px;
      border-radius: 13px;
      background: linear-gradient(180deg, #F0E9DD 0%, #E6DCCC 100%);
      border: 1px solid rgba(120, 90, 55, 0.22);
      box-shadow: 0 2px 7px rgba(74, 68, 61, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.6);
      cursor: pointer;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 14.5px;
      font-style: italic;
      font-weight: 600;
      color: #6B4A2A;
      letter-spacing: 0.01em;
      transition: transform 0.15s ease, box-shadow 0.15s ease;
    }
    .album-empty-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(74,68,61,0.12), inset 0 1px 0 rgba(255,255,255,0.6); }
    .album-empty-cta:active { transform: translateY(0); }
    /* Album search: point to Mail when the only match is something you sent. */
    .album-sent-hint {
      margin: 16px auto 0;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 14px;
      font-style: italic;
      color: rgba(80, 55, 30, 0.55);
      line-height: 1.5;
    }
    .album-sent-hint-link {
      background: none;
      border: none;
      padding: 0 0 1px;
      margin-left: 2px;
      cursor: pointer;
      font: inherit;
      color: #B4432D;
      border-bottom: 1px solid rgba(180, 67, 45, 0.4);
      white-space: nowrap;
    }
    .album-sent-hint-link:hover { color: #93341f; border-bottom-color: rgba(180,67,45,0.7); }
    /* Album first paint: skeleton cards while the cloud album loads, so a
       full album never flashes "empty" on open. */
    .kp-skel {
      position: relative;
      border-radius: 10px;
      min-height: 116px;
      padding: 14px 14px 12px;
      background: linear-gradient(180deg, #F3ECE0 0%, #ECE3D4 100%);
      border: 1px solid rgba(120, 90, 55, 0.10);
      box-shadow: 0 1px 3px rgba(74, 68, 61, 0.06), inset 0 1px 0 rgba(255,255,255,0.5);
      overflow: hidden;
    }
    .kp-skel::after {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(100deg, transparent 30%, rgba(255,252,245,0.55) 50%, transparent 70%);
      transform: translateX(-100%);
      animation: kpSkelShimmer 1.5s ease-in-out infinite;
    }
    .kp-skel-line { display: block; height: 11px; border-radius: 4px; background: rgba(120, 90, 55, 0.13); }
    .kp-skel-title { width: 70%; height: 14px; margin-bottom: 12px; }
    .kp-skel-sub { width: 45%; margin-bottom: 16px; }
    .kp-skel-snippet { width: 92%; margin-bottom: 7px; }
    .kp-skel-snippet2 { width: 78%; }
    .kp-skel-foot { display: block; width: 38%; height: 9px; border-radius: 4px; background: rgba(120,90,55,0.10); margin-top: 18px; }
    @keyframes kpSkelShimmer {
      0% { transform: translateX(-100%); }
      60%, 100% { transform: translateX(100%); }
    }

    /* ═════════════════════════════════════════════════════════════════
       PHASE B: KEEPSAKE-AS-ARTIFACT CARDS
       Each card is a small physical object. Shared paper base, layered
       shadows for material weight, then per-kind differentiators
       (postmark, envelope flap, wax seal, cassette silhouette, page-
       corner, mourning frame). Light source from upper-left. Hover
       lifts; press depresses.
       ═════════════════════════════════════════════════════════════════ */
    .kp-card {
      /* ═══ THE SINGLE LIGHT SOURCE ═══
         Every card in the album is lit by one diffused source from the
         upper-left, 10° off vertical. Shadows fall lower-right. The
         upper-left edge of each card catches a thin cream highlight;
         the lower-right edge falls into a thin warm-brown rim. This is
         the gallery lighting decision that unifies every keepsake into
         one room — regardless of kind, regardless of season.
         ── THE SHOEBOX ASYMMETRY ── (set inline per-item)
         --card-rotation and --card-y-offset are deterministic seeds
         derived from item.key. Same item, same album → same lean. */
      --card-rotation: 0deg;
      --card-y-offset: 0px;
      position: relative;
      display: block;
      width: 100%;
      text-align: left;
      cursor: pointer;
      border: none;
      padding: 12px 13px 10px;
      border-radius: 4px;
      min-height: 96px;
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,250,242,0.14) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #f5ecd6 0%, #e8dabc 100%);
      box-shadow:
        /* close shadow — light from upper-left, ~10° off vertical */
        1px 2px 4px rgba(70, 48, 22, 0.10),
        /* longer ambient shadow — preserves direction */
        2px 6px 16px rgba(70, 48, 22, 0.10),
        /* upper-left edge catches the light */
        inset 1px 1px 0 rgba(255, 252, 240, 0.70),
        /* lower-right edge falls into shadow */
        inset -1px -1px 1px rgba(120, 85, 40, 0.14);
      transform: rotate(var(--card-rotation)) translateY(var(--card-y-offset));
      transition:
        transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
        box-shadow 0.22s cubic-bezier(0.22, 1, 0.36, 1);
      overflow: hidden;
    }
    /* Paper texture — two layers: fine fibres on top of broad mottling.
       Like real premium stationery (cf. Morello envelope reference), the
       surface is uneven on two scales. The fine layer gives you fibres
       at reading distance; the broad layer gives you "the paper has
       weight" at glance distance. Matte multiply, not gloss. */
    .kp-card::before {
      content: '';
      position: absolute;
      inset: 0;
      pointer-events: none;
      background-image:
        /* fine paper fibres — visible at close range */
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='p'><feTurbulence type='fractalNoise' baseFrequency='1.4' numOctaves='2' seed='8'/><feColorMatrix values='0 0 0 0 0.30  0 0 0 0 0.20  0 0 0 0 0.10  0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23p)'/></svg>"),
        /* broad mottling — uneven density patches like handmade paper */
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='m'><feTurbulence type='fractalNoise' baseFrequency='0.05' numOctaves='3' seed='15'/><feColorMatrix values='0 0 0 0 0.20  0 0 0 0 0.14  0 0 0 0 0.08  0 0 0 0.30 0'/></filter><rect width='100%25' height='100%25' filter='url(%23m)'/></svg>");
      background-size: 180px 180px, 400px 400px;
      background-repeat: repeat, repeat;
      opacity: 0.22;
      mix-blend-mode: multiply;
    }
    .kp-card:hover {
      /* lifted toward the light — keeps the card's own lean intact */
      transform: rotate(var(--card-rotation)) translateY(calc(var(--card-y-offset) - 3px));
      box-shadow:
        2px 4px 10px rgba(70, 48, 22, 0.12),
        4px 12px 26px rgba(70, 48, 22, 0.16),
        inset 1px 1px 0 rgba(255, 252, 240, 0.80),
        inset -1px -1px 1px rgba(120, 85, 40, 0.16);
    }
    .kp-card:active {
      transform: rotate(var(--card-rotation)) translateY(var(--card-y-offset)) scale(0.985);
    }

    /* ═══ MIRYOKUTEKI PILLAR 四 — WEAR AT THE CORNER ═══
       Each open deepens a subtle scuff at the bottom-right of the card,
       where a real thumb would rest. The wear is multiply-blended onto
       the paper so it darkens without ever fighting text above it.
       Three thresholds:
         data-wear="1"  (3–9 opens)   faint thumb shadow only
         data-wear="2"  (10–29 opens) visible scuff + small abrasion
         data-wear="3"  (30+ opens)   pronounced wear + faint crease
       No badge. No counter. No words. Just the paper remembering. */
    .kp-card-wear {
      position: absolute;
      bottom: 0;
      right: 0;
      width: 38px;
      height: 38px;
      pointer-events: none;
      z-index: 1;
      mix-blend-mode: multiply;
      border-bottom-right-radius: 4px;
    }
    .kp-card-wear[data-wear="1"] {
      background:
        radial-gradient(circle 22px at 100% 100%,
          rgba(70, 48, 22, 0.11) 0%,
          rgba(70, 48, 22, 0.04) 45%,
          transparent 80%);
    }
    .kp-card-wear[data-wear="2"] {
      width: 46px;
      height: 44px;
      background:
        radial-gradient(circle 28px at 100% 100%,
          rgba(70, 48, 22, 0.15) 0%,
          rgba(70, 48, 22, 0.06) 38%,
          transparent 75%),
        radial-gradient(ellipse 16px 4px at 85% 92%,
          rgba(70, 48, 22, 0.09) 0%,
          transparent 85%);
    }
    .kp-card-wear[data-wear="3"] {
      width: 56px;
      height: 52px;
      background:
        radial-gradient(circle 34px at 100% 100%,
          rgba(70, 48, 22, 0.19) 0%,
          rgba(70, 48, 22, 0.08) 38%,
          transparent 75%),
        radial-gradient(ellipse 20px 5px at 84% 90%,
          rgba(70, 48, 22, 0.11) 0%,
          transparent 85%),
        /* an almost-imperceptible crease line at the very corner */
        linear-gradient(135deg,
          transparent 84%,
          rgba(70, 48, 22, 0.20) 90%,
          transparent 95%);
    }

    /* The "page" inside each card — content sits on top of all layers */
    .kp-card-body {
      position: relative;
      z-index: 2;
      display: flex;
      flex-direction: column;
      gap: 6px;
      height: 100%;
    }
    .kp-card-title {
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 13.5px;
      font-weight: 600;
      font-style: italic;
      color: #2e2014;
      line-height: 1.18;
      letter-spacing: -0.005em;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      padding-left: 22px;  /* clears the heart icon on the top-left */
      padding-right: 38px; /* clears the postmark on the top-right */
    }
    .kp-card-direction {
      font-family: 'DM Sans', sans-serif;
      font-size: 7.5px;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: rgba(95, 70, 40, 0.50);
      margin-top: 2px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      padding-left: 22px;
      padding-right: 38px;
    }
    .kp-card-snippet {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 11.5px;
      font-style: italic;
      color: rgba(70, 50, 30, 0.62);
      line-height: 1.30;
      margin-top: 4px;
      display: -webkit-box;
      -webkit-line-clamp: 1;
      -webkit-box-orient: vertical;
      overflow: hidden;
      padding-right: 34px;
    }
    .kp-card-kind-mark {
      position: absolute;
      bottom: 9px; left: 14px;
      font-family: 'DM Sans', sans-serif;
      font-size: 7.5px;
      font-weight: 700;
      letter-spacing: 0.18em;
      text-transform: uppercase;
      z-index: 3;
    }

    /* ── POSTMARK — date as a faded ring stamp top-right ── */
    .kp-postmark {
      position: absolute;
      top: 8px; right: 8px;
      width: 34px; height: 34px;
      z-index: 3;
      pointer-events: none;
      transform: rotate(-8deg);
      opacity: 0.58;
    }
    .kp-postmark svg { width: 100%; height: 100%; }
    .kp-postmark .pm-ring {
      fill: none;
      stroke: rgba(140, 50, 30, 0.55);
      stroke-width: 1;
    }
    .kp-postmark .pm-text {
      font-family: 'DM Sans', sans-serif;
      font-size: 6.5px;
      font-weight: 700;
      letter-spacing: 0.10em;
      fill: rgba(140, 50, 30, 0.60);
      text-transform: uppercase;
    }

    /* ── PORTRAIT STAMP — small circular avatar for sender/recipient ── */
    .kp-portrait-stamp {
      position: absolute;
      bottom: 9px; right: 11px;
      width: 28px; height: 28px;
      border-radius: 50%;
      background: linear-gradient(145deg, #d8c8a8, #b5a07a);
      box-shadow:
        0 1px 3px rgba(60, 40, 20, 0.30),
        inset 0 1px 0 rgba(255, 245, 220, 0.50);
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 11px;
      font-style: italic;
      font-weight: 600;
      color: #3d2818;
      z-index: 3;
      letter-spacing: -0.02em;
    }

    /* ═══ PER-KIND VARIANTS ═══ */

    /* Postcard: matte rose-cream — 1950s travel postcard, sun-aged */
    .kp-card.kp-card-postcard {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,248,236,0.14) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #f7e2c2 0%, #e0bf94 100%);
    }

    /* Letter: V-cut top edge suggesting an envelope flap +
       subtle wax-seal accent dot top-right corner */
    .kp-card.kp-card-letter {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,250,238,0.14) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #f3ebcc 0%, #dbc89b 100%);
      padding-top: 18px;
    }
    .kp-card.kp-card-letter::after {
      content: '';
      position: absolute;
      top: 0; left: 0; right: 0;
      height: 14px;
      background:
        linear-gradient(135deg, transparent 0%, transparent 49%, rgba(120,85,40,0.20) 50%, transparent 51%, transparent 100%),
        linear-gradient(225deg, transparent 0%, transparent 49%, rgba(120,85,40,0.20) 50%, transparent 51%, transparent 100%);
      background-size: 50% 100%, 50% 100%;
      background-position: 0 0, 100% 0;
      background-repeat: no-repeat;
      pointer-events: none;
      z-index: 1;
    }
    .kp-card.kp-card-letter .kp-wax-seal {
      position: absolute;
      top: 8px; right: 10px;
      width: 22px; height: 22px;
      border-radius: 50%;
      background:
        radial-gradient(circle at 30% 25%, #c44a33 0%, #9b2818 60%, #6b1a10 100%);
      box-shadow:
        0 2px 4px rgba(80, 15, 10, 0.45),
        inset 0 1px 1px rgba(255, 200, 180, 0.30),
        inset 0 -1px 2px rgba(0, 0, 0, 0.30);
      z-index: 3;
    }
    .kp-card.kp-card-letter .kp-wax-seal::after {
      content: 'P';
      position: absolute;
      inset: 0;
      display: flex; align-items: center; justify-content: center;
      font-family: 'Bodoni Moda', Georgia, serif;
      font-size: 10px;
      font-style: italic;
      font-weight: 600;
      color: rgba(255, 220, 200, 0.40);
    }

    /* Voicecard: matte sage — recording-studio acoustic-card paper */
    .kp-card.kp-card-voicecard {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(252,255,248,0.12) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #dfe6d7 0%, #b3c3a6 100%);
    }
    .kp-card.kp-card-voicecard .kp-voicecard-wave {
      position: absolute;
      bottom: 26px; left: 14px; right: 14px;
      height: 18px;
      pointer-events: none;
      z-index: 1;
      opacity: 0.45;
    }
    .kp-card.kp-card-voicecard .kp-voicecard-duration {
      position: absolute;
      bottom: 9px; right: 12px;
      font-family: 'DM Sans', monospace;
      font-size: 10px;
      font-weight: 600;
      letter-spacing: 0.06em;
      color: rgba(50, 75, 60, 0.75);
      z-index: 3;
    }

    /* Capsule: matte aged parchment with gold-leaf undertone */
    .kp-card.kp-card-capsule {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,246,220,0.12) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #e8d595 0%, #c79c54 100%);
    }
    .kp-card.kp-card-capsule.kp-card-capsule-locked {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,246,220,0.08) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #d3bc7e 0%, #a18443 100%);
    }
    .kp-card.kp-card-capsule .kp-card-snippet { filter: blur(0); }
    .kp-card.kp-card-capsule.kp-card-capsule-locked .kp-card-snippet { filter: blur(2.5px); opacity: 0.55; }
    .kp-card.kp-card-capsule .kp-capsule-status {
      position: absolute;
      bottom: 9px; right: 12px;
      font-family: 'DM Sans', sans-serif;
      font-size: 8px;
      font-weight: 700;
      letter-spacing: 0.16em;
      text-transform: uppercase;
      color: rgba(110, 75, 18, 0.75);
      z-index: 3;
    }
    .kp-card.kp-card-capsule.kp-card-capsule-ready .kp-capsule-status {
      color: rgba(155, 100, 25, 0.95);
    }

    /* Anthology: matte cloth-bound endpaper, warm tan */
    .kp-card.kp-card-anthology {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,248,232,0.13) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #e2cba9 0%, #c19972 100%);
      padding-right: 22px;
    }
    .kp-card.kp-card-anthology::after {
      content: '';
      position: absolute;
      top: 6px; bottom: 6px; right: 0;
      width: 8px;
      background:
        linear-gradient(90deg, rgba(120, 85, 40, 0.22) 0%, transparent 30%),
        repeating-linear-gradient(180deg,
          rgba(120, 85, 40, 0.18) 0px,
          rgba(120, 85, 40, 0.18) 1px,
          transparent 1px,
          transparent 4px);
      pointer-events: none;
      z-index: 1;
      border-radius: 0 3px 3px 0;
    }

    /* Diary: matte dove-cream, Moleskine page */
    .kp-card.kp-card-diary {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,251,242,0.16) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #ede2cb 0%, #d0c19f 100%);
    }
    .kp-card.kp-card-diary .kp-card-snippet { font-size: 13px; }

    /* ═══ SHELF CARD — group "stack" form ═══
       Three overlapping mini cards behind a top label card. The
       mini cards peek from behind, suggesting depth and collection. */
    .kp-shelf {
      position: relative;
      display: block;
      width: 100%;
      cursor: pointer;
      border: none;
      background: transparent;
      padding: 0;
      aspect-ratio: 2 / 1;
      transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .kp-shelf:hover { transform: translateY(-3px); }
    .kp-shelf:hover .kp-shelf-stack-back  { transform: translate(-6px, -3px) rotate(-2.5deg); }
    .kp-shelf:hover .kp-shelf-stack-mid   { transform: translate(0, -2px) rotate(-1deg); }
    .kp-shelf:active { transform: translateY(0) scale(0.985); }

    .kp-shelf-stack-back,
    .kp-shelf-stack-mid,
    .kp-shelf-stack-front {
      position: absolute;
      inset: 0;
      border-radius: 4px;
      transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .kp-shelf-stack-back {
      /* same upper-left light source — back layer in deepest shadow */
      background: linear-gradient(168deg, #ede0c4, #d8c8a8);
      transform: translate(-3px, 1px) rotate(-1.8deg);
      box-shadow: 1px 2px 6px rgba(60, 40, 20, 0.10);
      z-index: 1;
    }
    .kp-shelf-stack-mid {
      background: linear-gradient(168deg, #f4ead2, #e4d3b4);
      transform: translate(2px, -1px) rotate(0.8deg);
      box-shadow: 1px 2px 6px rgba(60, 40, 20, 0.10);
      z-index: 2;
    }
    .kp-shelf-stack-front {
      background:
        radial-gradient(ellipse 90% 50% at 30% 0%, rgba(255,250,242,0.14) 0%, rgba(255,255,255,0) 50%),
        linear-gradient(168deg, #f5ecd6 0%, #e8dabc 100%);
      box-shadow:
        1px 2px 4px rgba(70, 48, 22, 0.12),
        2px 6px 14px rgba(70, 48, 22, 0.12),
        inset 1px 1px 0 rgba(255, 252, 240, 0.70),
        inset -1px -1px 1px rgba(120, 85, 40, 0.14);
      z-index: 3;
      padding: 14px 14px 12px;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    .kp-shelf-title {
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 17px;
      font-weight: 600;
      font-style: italic;
      color: #2a1810;
      line-height: 1.15;
      letter-spacing: -0.01em;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .kp-shelf-subtitle {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px;
      font-style: italic;
      color: rgba(95, 70, 40, 0.62);
      margin-top: 2px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .kp-shelf-count {
      font-family: 'DM Sans', sans-serif;
      font-size: 8.5px;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: rgba(95, 70, 40, 0.42);
      margin-top: 8px;
    }
    .kp-shelf-accent {
      position: absolute;
      top: 10px; right: 12px;
      width: 8px; height: 8px;
      border-radius: 50%;
      z-index: 4;
      box-shadow: 0 1px 2px rgba(40, 25, 10, 0.30);
    }

    /* ═════════════════════════════════════════════════════════════════
       PHASE F: COMPACT SHELF-CARD FORMAT
       Per-item cards adopt the 2:1 shelf-card format used previously
       for People/Kinds/Years groups. Flat 2-column grid. Title +
       snippet + footer (kind · date). Accent stripe on left edge for
       kind identification.
       ═════════════════════════════════════════════════════════════════ */
    /* Compact 2-col card that holds the full keepsake copy.
       Title / direction / snippet / footer (kind + date) all in.
       Content-driven height (min 124, grows for long previews). */
    .kp-card.kp-shelf-item {
      aspect-ratio: auto;
      min-height: 124px;
      padding: 11px 13px 11px 19px;   /* left padding clears the accent stripe */
      display: block;
      overflow: hidden;
    }
    .kp-shelf-accent-stripe {
      position: absolute;
      left: 0; top: 0; bottom: 0;
      width: 5px;
      opacity: 0.78;
      z-index: 2;
      pointer-events: none;
    }
    .kp-shelf-inner-border {
      position: absolute;
      top: 7px; bottom: 7px; left: 13px; right: 7px;
      border: 1px solid rgba(90, 74, 61, 0.14);
      border-radius: 4px;
      pointer-events: none;
      z-index: 2;
    }
    .kp-shelf-content {
      position: relative;
      z-index: 3;
      display: flex;
      flex-direction: column;
      height: 100%;
      gap: 0;
    }
    /* Top row: title (left, ellipsis) — heart sits to the right of it */
    .kp-shelf-content .kp-shelf-title {
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 13.5px;
      font-weight: 600;
      font-style: italic;
      color: #2e2014;
      line-height: 1.2;
      letter-spacing: -0.005em;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      padding-right: 26px;
      /* Strong letterpress — the title is pressed firmly into the paper */
      text-shadow:
        0 1px 0 rgba(255, 250, 240, 0.55),
        0 -0.5px 0 rgba(60, 38, 15, 0.07);
    }
    .kp-shelf-content .kp-shelf-direction {
      font-family: 'DM Sans', sans-serif;
      font-size: 8px;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: rgba(95, 70, 40, 0.52);
      margin-top: 3px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      text-shadow: 0 0.5px 0 rgba(255, 250, 240, 0.45);
    }
    .kp-shelf-content .kp-shelf-snippet {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 11.5px;
      font-style: italic;
      color: rgba(70, 50, 30, 0.62);
      line-height: 1.32;
      margin-top: 5px;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-shadow: 0 1px 0 rgba(255, 250, 240, 0.48);
    }
    .kp-shelf-content .kp-shelf-footer {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
      margin-top: auto;
      padding-top: 6px;
      gap: 8px;
      min-height: 14px;
    }
    .kp-shelf-content .kp-shelf-kind {
      font-family: 'DM Sans', sans-serif;
      font-size: 7.5px;
      font-weight: 700;
      letter-spacing: 0.16em;
      text-transform: uppercase;
      opacity: 0.78;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      display: inline-flex;
      align-items: center;
      gap: 5px;
      text-shadow: 0 0.5px 0 rgba(255, 250, 240, 0.45);
    }
    .kp-shelf-content .kp-shelf-badge {
      display: inline-flex;
      align-items: center;
      padding: 1px 6px;
      border-radius: 8px;
      background: rgba(90, 74, 61, 0.08);
      border: 1px solid rgba(90, 74, 61, 0.12);
      font-family: 'DM Sans', sans-serif;
      font-size: 7.5px;
      font-weight: 600;
      letter-spacing: 0.08em;
      color: rgba(70, 55, 42, 0.62);
      text-transform: uppercase;
    }
    .kp-shelf-content .kp-shelf-date {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 10.5px;
      font-style: italic;
      color: rgba(95, 70, 40, 0.55);
      white-space: nowrap;
      text-shadow: 0 1px 0 rgba(255, 250, 240, 0.48);
      letter-spacing: 0.01em;
    }
    /* Heart top-right corner, away from accent stripe */
    .kp-card.kp-shelf-item .kp-heart {
      top: 5px; right: 5px; left: auto;
    }
    /* Ribbon hangs from top-right of the inner border on a shelf item */
    .kp-card.kp-shelf-item .kp-ribbon {
      top: -2px;
      right: 18px;
      left: auto;
      transform: none;
    }

    /* ═════════════════════════════════════════════════════════════════
       PHASE D: HEIRLOOM POLISH
       Per-kind real form differentiation (postcard wide, letter
       portrait with folded silhouette, voicecard square, capsule
       sealed-envelope, anthology bound spread, diary page). Favorites
       with a ribbon bookmark. Postage-stamp serrated portrait.
       Personalized wax seal initial. Confident paper grain.
       ═════════════════════════════════════════════════════════════════ */

    /* ── Confident paper grain (was 10% → now 18%) ── */
    .kp-card::before {
      opacity: 0.18 !important;
    }

    /* ── Heart icon: small tap target in the top-left of every card ── */
    .kp-heart {
      position: absolute;
      top: 6px; left: 6px;
      width: 22px; height: 22px;
      border-radius: 50%;
      display: flex; align-items: center; justify-content: center;
      z-index: 5;
      background: transparent;
      border: none;
      cursor: pointer;
      color: rgba(120, 90, 55, 0.32);
      transition: color 0.16s ease, transform 0.12s ease;
    }
    .kp-heart:hover { color: rgba(180, 67, 45, 0.85); transform: scale(1.12); }
    .kp-heart:active { transform: scale(0.92); }
    .kp-heart svg { width: 13px; height: 13px; }
    .kp-heart.kp-heart-filled {
      color: #b4432d;
    }
    .kp-heart.kp-heart-filled svg path {
      fill: currentColor;
      stroke: currentColor;
    }

    /* ── Ribbon bookmark — hangs from top-center of favorited cards.
       Centered so it stays clear of the top-left heart and the
       top-right postmark stamp. ── */
    .kp-ribbon {
      position: absolute;
      top: -2px;
      left: 50%;
      transform: translateX(-50%);
      width: 16px;
      z-index: 4;
      pointer-events: none;
      filter: drop-shadow(0 2px 3px rgba(80, 25, 15, 0.30));
    }
    .kp-ribbon svg { width: 100%; display: block; }

    /* ── Postage-stamp portrait — rectangular, serrated edges,
       script initials inside a paper-cream window. Replaces the
       circle "two letters" stamp from Phase B. ── */
    .kp-portrait-stamp.kp-postage-portrait {
      width: 26px; height: 30px;
      border-radius: 0;
      background:
        linear-gradient(168deg, #f6e9c8 0%, #e8d4a4 100%);
      /* Serrated edges via SVG mask (a stamp's perforations) */
      -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 40'><defs><pattern id='dot' x='0' y='0' width='4' height='4' patternUnits='userSpaceOnUse'><circle cx='2' cy='2' r='1.6' fill='black'/></pattern></defs><rect x='2' y='2' width='30' height='36' fill='white' rx='0'/><rect width='34' height='4' fill='url(%23dot)'/><rect y='36' width='34' height='4' fill='url(%23dot)'/><rect width='4' height='40' fill='url(%23dot)'/><rect x='30' width='4' height='40' fill='url(%23dot)'/></svg>");
      mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 40'><defs><pattern id='dot' x='0' y='0' width='4' height='4' patternUnits='userSpaceOnUse'><circle cx='2' cy='2' r='1.6' fill='black'/></pattern></defs><rect x='2' y='2' width='30' height='36' fill='white' rx='0'/><rect width='34' height='4' fill='url(%23dot)'/><rect y='36' width='34' height='4' fill='url(%23dot)'/><rect width='4' height='40' fill='url(%23dot)'/><rect x='30' width='4' height='40' fill='url(%23dot)'/></svg>");
      -webkit-mask-size: 100% 100%;
      mask-size: 100% 100%;
      box-shadow:
        0 1px 3px rgba(60, 40, 20, 0.28),
        inset 0 1px 0 rgba(255, 245, 220, 0.55);
      font-family: 'Bodoni Moda', 'Playfair Display', Georgia, serif;
      font-size: 13px;
      font-style: italic;
      font-weight: 600;
      letter-spacing: -0.04em;
      color: #3a2818;
    }

    /* ── PER-KIND REAL FORMS ──
       Each kind now has its own aspect / silhouette / dominant
       element. List-view-only — the All / Favorites / group-detail
       columns let cards take their natural shape. */

    /* POSTCARD — 6:4 wide rectangle, deckled bottom edge cue */
    .kp-card.kp-card-postcard {
      /* aspect removed — list-view thumbnails kept scannable */
/* min-height inherited from .kp-card base */
      padding: 16px 18px 18px;
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.50) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #fff8ec 0%, #f1e3c8 100%);
    }
    .kp-card.kp-card-postcard .kp-card-title { font-size: 17px; }
    .kp-card.kp-card-postcard .kp-card-snippet {
      font-size: 14px;
      -webkit-line-clamp: 3;
      margin-top: 8px;
    }

    /* LETTER — taller portrait, with a real folded silhouette
       cue (V flap at top, deeper) and the wax seal moved to the
       right edge mid-height like a real letter seal */
    .kp-card.kp-card-letter {
      /* aspect removed — list-view thumbnails kept scannable */
/* min-height inherited from .kp-card base */
      padding-top: 22px;
      padding-right: 36px;
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.48) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #fbf4e3 0%, #e6d3a8 100%);
    }
    .kp-card.kp-card-letter::after {
      content: '';
      position: absolute;
      top: 0; left: 0; right: 0;
      height: 20px;
      background:
        linear-gradient(135deg, transparent 0%, transparent 49.5%, rgba(120,85,40,0.26) 50%, transparent 50.5%, transparent 100%),
        linear-gradient(225deg, transparent 0%, transparent 49.5%, rgba(120,85,40,0.26) 50%, transparent 50.5%, transparent 100%);
      background-size: 50% 100%, 50% 100%;
      background-position: 0 0, 100% 0;
      background-repeat: no-repeat;
      pointer-events: none;
      z-index: 1;
    }
    /* Neutralize the old hardcoded "P" — wax seal now shows the
       sender's first initial as direct text content */
    .kp-card.kp-card-letter .kp-wax-seal::after { content: none !important; }
    /* Wax seal moved to right edge, mid-height */
    .kp-card.kp-card-letter .kp-wax-seal {
      position: absolute;
      top: 50%; right: 8px;
      transform: translateY(-50%);
      width: 28px; height: 28px;
      border-radius: 50%;
      background:
        radial-gradient(circle at 30% 25%, #c44a33 0%, #9b2818 60%, #6b1a10 100%);
      box-shadow:
        0 3px 6px rgba(80, 15, 10, 0.45),
        inset 0 1px 1px rgba(255, 200, 180, 0.35),
        inset 0 -1px 2px rgba(0, 0, 0, 0.30);
      z-index: 3;
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: 'Bodoni Moda', Georgia, serif;
      font-size: 14px;
      font-style: italic;
      font-weight: 600;
      color: rgba(255, 230, 215, 0.65);
      text-shadow: 0 1px 0 rgba(80, 15, 10, 0.45);
    }
    .kp-card.kp-card-letter .kp-card-snippet {
      -webkit-line-clamp: 4;
    }

    /* VOICECARD — squarish, soundwave dominant, duration big */
    .kp-card.kp-card-voicecard {
      /* aspect removed — list-view thumbnails kept scannable */
/* min-height inherited from .kp-card base */
      padding: 16px 16px 18px;
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.46) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #eef3e9 0%, #c8d4c0 100%);
    }
    .kp-card.kp-card-voicecard .kp-voicecard-wave {
      position: absolute;
      bottom: 26px; left: 14px; right: 14px;
      height: 14px;
      opacity: 0.45;
    }
    .kp-card.kp-card-voicecard .kp-voicecard-duration {
      position: absolute;
      bottom: 10px; right: 14px;
      font-family: 'Bodoni Moda', Georgia, serif;
      font-size: 13px;
      font-style: italic;
      font-weight: 500;
      letter-spacing: -0.01em;
      color: rgba(40, 65, 55, 0.85);
    }

    /* CAPSULE — sealed envelope, visible flap triangle on top half */
    .kp-card.kp-card-capsule {
      /* aspect removed — list-view thumbnails kept scannable */
      padding: 22px 14px 12px;
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.42) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #f5ead2 0%, #d4be86 100%);
    }
    /* Envelope flap — triangle pointing down, painted via SVG so it
       scales with the card width. Compact for thumbnail use. */
    .kp-card.kp-card-capsule::after {
      content: '';
      position: absolute;
      top: 0; left: 0; right: 0;
      height: 22px;
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 22' preserveAspectRatio='none'><polygon points='0,0 100,0 50,22' fill='rgba(120,85,40,0.22)'/><polyline points='0,0 50,22 100,0' stroke='rgba(80,55,25,0.20)' stroke-width='0.4' fill='none'/></svg>");
      background-size: 100% 100%;
      background-repeat: no-repeat;
      pointer-events: none;
      z-index: 1;
    }
    .kp-card.kp-card-capsule .kp-capsule-seal {
      position: absolute;
      top: 18px; left: 50%;
      transform: translate(-50%, -50%);
      width: 18px; height: 18px;
      border-radius: 50%;
      background: radial-gradient(circle at 30% 25%, #d49c2d 0%, #a67520 60%, #6b4810 100%);
      box-shadow: 0 2px 4px rgba(80, 50, 10, 0.40), inset 0 1px 0 rgba(255, 240, 200, 0.45);
      z-index: 3;
    }

    /* ANTHOLOGY — bound spread, multiple visible page edges */
    .kp-card.kp-card-anthology {
      /* aspect removed — list-view thumbnails kept scannable */
/* min-height inherited from .kp-card base */
      padding-right: 26px;
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.42) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #f7ecd8 0%, #d8c19a 100%);
    }
    .kp-card.kp-card-anthology::after {
      content: '';
      position: absolute;
      top: 6px; bottom: 6px; right: 0;
      width: 12px;
      background:
        linear-gradient(90deg, rgba(120, 85, 40, 0.26) 0%, transparent 30%),
        repeating-linear-gradient(180deg,
          rgba(120, 85, 40, 0.20) 0px,
          rgba(120, 85, 40, 0.20) 1px,
          transparent 1px,
          transparent 5px);
      pointer-events: none;
      z-index: 1;
      border-radius: 0 3px 3px 0;
    }
    .kp-card.kp-card-anthology .kp-card-snippet { -webkit-line-clamp: 4; }

    /* DIARY — page-corner card with subtle dog-eared corner */
    .kp-card.kp-card-diary {
      /* aspect removed — list-view thumbnails kept scannable */
/* min-height inherited from .kp-card base */
      background:
        radial-gradient(ellipse 110% 70% at 25% 0%, rgba(255,255,255,0.50) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(168deg, #fefbf2 0%, #ebe1c8 100%);
    }
    /* Dog-eared corner top-right */
    .kp-card.kp-card-diary::after {
      content: '';
      position: absolute;
      top: 0; right: 0;
      width: 22px; height: 22px;
      background:
        linear-gradient(225deg, rgba(160, 130, 80, 0.30) 0%, rgba(160, 130, 80, 0.10) 50%, rgba(255, 250, 235, 0.85) 51%, rgba(245, 235, 215, 1) 100%);
      pointer-events: none;
      z-index: 2;
      clip-path: polygon(0 0, 100% 0, 100% 100%);
    }
    .kp-card.kp-card-diary .kp-card-snippet { -webkit-line-clamp: 5; font-size: 13.5px; }

    /* Once forms are kind-specific, the bottom-left "Postcard / Letter"
       label is redundant. Hide it everywhere — the silhouette tells. */
    .kp-card .kp-card-kind-mark { display: none; }

    /* Tighter header type — drop DM Sans from kept-since; keep the
       whisper in the Cormorant family, smaller + lower opacity. */
    .album-header-since {
      font-family: 'Cormorant Garamond', Georgia, serif !important;
      font-size: 11.5px !important;
      font-weight: 400 !important;
      font-style: italic !important;
      letter-spacing: 0.04em !important;
      text-transform: none !important;
      color: rgba(95, 70, 40, 0.55) !important;
      margin-top: 8px !important;
    }

    /* ═════════════════════════════════════════════════════════════════
       PHASE C: THE REWARD LAYER
       Year-heading section dividers, "since you last visited" murmur,
       refined cover-to-interior choreography. The album earns its
       loyalty by rewarding the return with one new tiny detail.
       ═════════════════════════════════════════════════════════════════ */

    /* Letterpress section dividers — Bodoni italic + hairline rules */
    .kp-section-divider {
      display: flex;
      align-items: baseline;
      gap: 14px;
      margin: 26px 4px 14px;
    }
    .kp-section-divider-rule {
      flex: 1;
      height: 1px;
      background: linear-gradient(90deg, transparent, rgba(120, 90, 55, 0.32), transparent);
    }
    .kp-section-divider-label {
      font-family: 'Bodoni Moda', 'Playfair Display', Georgia, serif;
      font-size: 17px;
      font-style: italic;
      font-weight: 500;
      color: rgba(58, 38, 18, 0.80);
      letter-spacing: -0.005em;
      white-space: nowrap;
    }
    .kp-section-divider-label.kp-year-marker {
      font-size: 28px;
      font-weight: 500;
      color: rgba(40, 22, 8, 0.88);
      letter-spacing: -0.02em;
    }
    /* First section ("Recently added") gets a quieter, smaller treatment */
    .kp-section-divider.kp-section-divider-recent .kp-section-divider-label {
      font-family: 'DM Sans', sans-serif;
      font-size: 9.5px;
      font-weight: 600;
      letter-spacing: 0.22em;
      text-transform: uppercase;
      font-style: normal;
      color: rgba(95, 70, 40, 0.50);
    }

    /* "Since you last visited" murmur — italic line below header */
    .album-murmur {
      max-width: 540px;
      margin: -10px auto 18px;
      text-align: center;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 13.5px;
      font-style: italic;
      color: rgba(180, 67, 45, 0.72);
      letter-spacing: 0.01em;
      opacity: 0;
      transition: opacity 0.7s ease-out;
    }
    .album-murmur.visible { opacity: 1; }
    .album-murmur::before,
    .album-murmur::after {
      content: '·';
      margin: 0 8px;
      color: rgba(180, 67, 45, 0.45);
    }

    /* Cover screen refinement — soft fade-in + breathing hint */
    @keyframes album-cover-fade-in {
      0%   { opacity: 0; filter: blur(8px); }
      40%  { opacity: 1; filter: blur(4px); }
      100% { opacity: 1; filter: blur(0); }
    }
    @keyframes album-hint-breathe {
      0%, 100% { opacity: 0.42; transform: translateY(0); }
      50%      { opacity: 0.62; transform: translateY(-1px); }
    }
    #album-cover-screen.active #album-cover-wrapper {
      animation: album-cover-fade-in 1.2s cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    #album-cover-screen.active #album-cover-hint.album-hint-active {
      animation: album-hint-breathe 3.6s ease-in-out infinite;
    }

    /* Soft settle animation when album content arrives */
    @keyframes album-settle {
      0%   { opacity: 0; transform: translateY(6px); }
      100% { opacity: 1; transform: translateY(0); }
    }
    #album-screen.active .album-header,
    #album-screen.active .album-filter-strip,
    #album-screen.active .album-search-slip,
    #album-screen.active #album-categories {
      animation: album-settle 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
    }
    #album-screen.active .album-filter-strip { animation-delay: 0.06s; }
    #album-screen.active .album-search-slip  { animation-delay: 0.12s; }
    #album-screen.active #album-categories   { animation-delay: 0.18s; }

    /* ═════════════════════════════════════════════════════════════════
       DRAFTS SYSTEM — home "Continue your work" rail + #drafts-screen
       + discard confirmation sheet. Warm cream paper aesthetic to sit
       quietly beside the keepsake CTA cards without competing.
       ═════════════════════════════════════════════════════════════════ */
    .home-drafts-rail {
      width: 100%;
      /* 340px matches the visible Letter/Groupsake card row beneath which the
         rail now sits (the two cards are each capped at 165px + gap, so the
         row is ~334-344px wide depending on screen). Centered via margin auto
         so its edges track the cards above it. */
      max-width: 340px;
      margin: 14px auto 4px;
      padding: 11px 12px 9px;
      background: linear-gradient(180deg, #f8f1e3 0%, #efe4cb 100%);
      border-radius: 12px;
      border: 1px solid rgba(140, 100, 60, 0.16);
      box-shadow:
        0 2px 6px rgba(80, 60, 30, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.55);
    }
    .drafts-rail-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 8px;
      padding: 0 2px;
    }
    .drafts-rail-title {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 13px;
      font-style: italic;
      color: rgba(85, 60, 30, 0.72);
      letter-spacing: 0.04em;
    }
    .drafts-rail-list {
      display: flex;
      flex-direction: column;
      gap: 5px;
    }
    .draft-row {
      display: flex;
      align-items: center;
      gap: 9px;
      padding: 8px 8px 8px 10px;
      background: rgba(255, 252, 244, 0.55);
      border-radius: 8px;
      border: 1px solid rgba(140, 100, 60, 0.10);
      cursor: pointer;
      text-align: left;
      width: 100%;
      transition: background 0.16s ease, border-color 0.16s ease, transform 0.12s ease;
      position: relative;
    }
    .draft-row:hover { background: rgba(255, 252, 244, 0.8); border-color: rgba(140, 100, 60, 0.18); }
    .draft-row:active { transform: scale(0.985); }
    .draft-row-icon {
      width: 28px; height: 28px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: linear-gradient(180deg, rgba(255,255,255,0.6), rgba(255,250,238,0.4));
      border: 1px solid rgba(140, 100, 60, 0.16);
      border-radius: 6px;
      font-size: 14px;
    }
    .draft-row-content { flex: 1; min-width: 0; }
    .draft-row-title {
      font-family: 'DM Sans', sans-serif;
      font-size: 12.5px;
      font-weight: 500;
      color: #4a3a28;
      letter-spacing: 0.01em;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .draft-row-snippet {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px;
      font-style: italic;
      color: rgba(95, 70, 45, 0.62);
      margin-top: 1px;
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .draft-row-time {
      font-family: 'DM Sans', sans-serif;
      font-size: 9px;
      font-weight: 600;
      letter-spacing: 0.10em;
      text-transform: uppercase;
      color: rgba(95, 70, 45, 0.45);
      margin-top: 3px;
    }
    .draft-row-menu {
      flex-shrink: 0;
      width: 26px; height: 26px;
      display: flex; align-items: center; justify-content: center;
      border-radius: 6px;
      background: transparent;
      color: rgba(95, 70, 45, 0.5);
      font-size: 16px; line-height: 1;
      border: none;
      cursor: pointer;
      padding: 0;
    }
    .draft-row-menu:hover { background: rgba(140, 100, 60, 0.12); color: rgba(60, 40, 20, 0.85); }
    .drafts-rail-seeall {
      display: block;
      margin: 8px auto 0;
      padding: 6px 10px;
      background: transparent;
      border: none;
      color: rgba(85, 60, 30, 0.75);
      font-family: 'DM Sans', sans-serif;
      font-size: 11px;
      font-weight: 500;
      letter-spacing: 0.04em;
      cursor: pointer;
    }
    .drafts-rail-seeall:hover { color: rgba(50, 30, 10, 0.95); }

    /* ── Full Drafts screen ── */
    #drafts-screen main { padding: 0 20px 80px; }
    .drafts-screen-list {
      max-width: 540px; margin: 0 auto;
      display: flex; flex-direction: column; gap: 8px;
    }
    .drafts-screen-empty {
      max-width: 360px; margin: 60px auto 0;
      text-align: center;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 15px; font-style: italic;
      color: rgba(95, 70, 45, 0.62);
      line-height: 1.5;
    }
    .drafts-screen-empty-icon {
      width: 64px; height: 64px;
      margin: 0 auto 14px;
      border-radius: 50%;
      background: linear-gradient(145deg, #f8f4ee, #ede5d8);
      box-shadow: 0 4px 14px rgba(140, 110, 80, 0.12);
      display: flex; align-items: center; justify-content: center;
      font-size: 26px;
    }
    .drafts-screen-row {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 14px 12px;
      background: #fdf9ed;
      border: 1px solid rgba(140, 100, 60, 0.14);
      border-radius: 12px;
      cursor: pointer;
      text-align: left;
      width: 100%;
      box-shadow: 0 1px 3px rgba(80, 60, 30, 0.06);
      transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease;
    }
    .drafts-screen-row:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 10px rgba(80, 60, 30, 0.10);
      border-color: rgba(140, 100, 60, 0.22);
    }
    .drafts-screen-row .draft-row-icon { width: 38px; height: 38px; font-size: 18px; }
    .drafts-screen-row .draft-row-title { font-size: 14px; }
    .drafts-screen-row .draft-row-snippet { font-size: 13px; }
    .drafts-screen-row .draft-row-time { font-size: 10px; }
    .drafts-screen-row .draft-row-menu { width: 32px; height: 32px; font-size: 18px; }

    /* ── Discard confirmation sheet ── */
    .discard-sheet-overlay {
      position: fixed; inset: 0;
      background: rgba(20, 14, 8, 0.50);
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
      z-index: 1000;
      display: flex; align-items: flex-end; justify-content: center;
      opacity: 0;
      transition: opacity 0.22s ease;
    }
    .discard-sheet-overlay.open { opacity: 1; }
    .discard-sheet {
      width: 100%;
      max-width: 460px;
      margin-bottom: 16px;
      background: linear-gradient(180deg, #fbf6eb 0%, #f3eada 100%);
      border-radius: 18px 18px 18px 18px;
      padding: 22px 24px 18px;
      box-shadow: 0 20px 60px rgba(40, 25, 10, 0.45);
      transform: translateY(20px);
      transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .discard-sheet-overlay.open .discard-sheet { transform: translateY(0); }
    .discard-sheet-title {
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 19px;
      font-style: italic;
      font-weight: 600;
      color: #3a2818;
      margin: 0 0 6px;
      text-align: center;
    }
    .discard-sheet-body {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 14px;
      font-style: italic;
      color: rgba(80, 55, 30, 0.72);
      text-align: center;
      margin: 0 0 18px;
      line-height: 1.45;
    }
    .discard-sheet-actions {
      display: flex; gap: 10px;
    }
    .discard-sheet-btn {
      flex: 1;
      padding: 12px 14px;
      border-radius: 10px;
      font-family: 'DM Sans', sans-serif;
      font-size: 13px;
      font-weight: 500;
      letter-spacing: 0.04em;
      cursor: pointer;
      transition: transform 0.12s ease, background 0.16s ease;
      border: none;
    }
    .discard-sheet-btn:active { transform: scale(0.97); }
    .discard-sheet-btn-keep {
      background: linear-gradient(180deg, #f4ecdc, #e6d9bf);
      color: #3a2818;
      border: 1px solid rgba(140, 100, 60, 0.25);
    }
    .discard-sheet-btn-discard {
      background: linear-gradient(180deg, #c44a33, #a83820);
      color: #fdf6e8;
      box-shadow: 0 2px 6px rgba(120, 40, 25, 0.30);
    }

    /* ═══ LIVING INK — character state styles ═══ */
    .ink-char {
      display: inline;
      transition: filter 1200ms ease-out, opacity 800ms ease-out, color 1200ms ease-out;
    }
    .ink-char.wet {
      filter: url(#ink-wet-filter);
      opacity: 0.85;
      color: var(--ink-wet, #1A1B26);
    }
    .ink-char.bleeding {
      filter: url(#ink-bleed-filter);
      opacity: 0.9;
      color: var(--ink-wet, #1A1B26);
    }
    .ink-char.dry {
      filter: none;
      opacity: 1;
      color: var(--ink-dry, #1F2028);
    }
    .ink-char.heavy-bleed {
      filter: url(#ink-heavy-bleed-filter);
      opacity: 0.88;
      color: var(--ink-wet, #181922);
    }
    
    /* ═══ MATERIAL MORPHS — Dynamic texture response per Hallmark family ═══ */
    #journal-diary-page {
      --material-brightness: 1;
      --material-shadow: 0 0 0 transparent;
      --material-transition: 800ms cubic-bezier(0.22, 1, 0.36, 1);
      transition: filter var(--material-transition), box-shadow var(--material-transition);
    }
    .material-overlay {
      position: absolute; inset: 0; pointer-events: none; z-index: 0;
      opacity: 0;
      transition: opacity 800ms cubic-bezier(0.22, 1, 0.36, 1);
      mix-blend-mode: multiply;
    }
    .material-overlay.active { opacity: 1; }
    /* Light response states */
    .material-matte #journal-diary-page {
      filter: brightness(0.97) saturate(0.95);
      box-shadow: 
        0 1px 0 rgba(180,165,140,0.3),0 2px 0 rgba(170,155,130,0.15),
        0 4px 12px rgba(60,40,20,0.14),0 8px 24px rgba(40,25,10,0.1),
        inset 0 0 0 0.5px rgba(180,165,140,0.25);
    }
    .material-lustre #journal-diary-page {
      filter: brightness(1.03) saturate(1.05);
      box-shadow: 
        0 1px 0 rgba(180,165,140,0.3),0 2px 0 rgba(170,155,130,0.15),
        0 4px 12px rgba(60,40,20,0.1),0 8px 24px rgba(40,25,10,0.06),
        0 0 20px rgba(255,248,235,0.08),
        inset 0 0 0 0.5px rgba(180,165,140,0.25);
    }
    .material-pressed #journal-diary-page {
      filter: brightness(1) saturate(0.98) contrast(1.02);
      box-shadow: 
        0 1px 0 rgba(180,165,140,0.35),0 2px 0 rgba(170,155,130,0.2),
        0 4px 12px rgba(60,40,20,0.16),0 8px 24px rgba(40,25,10,0.1),
        inset 0 0 0 0.5px rgba(180,165,140,0.3);
    }
    .material-morph-flash {
      animation: material-flash 600ms ease-out;
    }
    @keyframes material-flash {
      0% { filter: brightness(1.08); }
      100% { filter: brightness(1); }
    }
    
    /* ═══ HALLMARK HERITAGE — Debossed maker's marks ═══ */
    .hallmark-glow {
      animation: hallmark-seal-glow 0.8s ease-out;
    }
    @keyframes hallmark-seal-glow {
      0% { filter: url(#hallmark-emboss) drop-shadow(0 0 4px rgba(212,175,55,0.6)); }
      100% { filter: url(#hallmark-emboss) drop-shadow(0 0 0 transparent); }
    }
    
    /* Ticket drag styles */
    .postcard-ticket {
      touch-action: none;
    }
    .postcard-ticket:hover {
      filter: drop-shadow(0 3px 6px rgba(0,0,0,0.25)) !important;
    }
    .postcard-ticket:active {
      cursor: grabbing !important;
    }
    .postcard-message-area {
      transition: left 0.3s ease, right 0.3s ease, bottom 0.3s ease, top 0.3s ease;
    }
    .postcard-stamp-flow-spacer {
      float: right;
      width: var(--pc-stamp-flow-width, 64px);
      height: var(--pc-stamp-flow-height, 68px);
      pointer-events: none;
      user-select: none;
    }
    #postcard-textarea::-webkit-scrollbar {
      display: none;
    }
    /* Pin placeholder to top-left so it always sits where the first line of
       text actually begins — not wherever the floated stamp-spacer pushes
       the inline flow to. */
    #postcard-textarea[data-empty="true"]::after {
      content: attr(data-placeholder);
      color: rgba(90, 74, 61, 0.38);
      pointer-events: none;
      position: absolute;
      top: 0;
      left: 0;
    }
    
    /* Dunbar Circles Styles */
    .dunbar-container {
      touch-action: manipulation;
    }
    
    .dunbar-ring {
      cursor: pointer;
    }
    
    .dunbar-ring .ring-bg {
      transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
    }
    
    .dunbar-ring:hover .ring-bg {
      stroke-opacity: 0.9 !important;
      stroke-width: 22 !important;
    }
    
    .dunbar-ring.selected .ring-bg {
      stroke-opacity: 1 !important;
      stroke-width: 24 !important;
      filter: url(#glow-1);
    }
    
    @keyframes ring-pulse {
      0%, 100% { stroke-opacity: 1; }
      50% { stroke-opacity: 0.75; }
    }
    
    .dunbar-ring.selected .ring-bg {
      animation: ring-pulse 2.5s ease-in-out infinite;
    }
    
    .dunbar-person {
      transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
      cursor: pointer;
    }
    
    .dunbar-person:hover {
      transform: scale(1.4);
    }
    
    .dunbar-person.selected circle {
      stroke-width: 3 !important;
      filter: drop-shadow(0 0 6px currentColor);
    }
    
    .dunbar-legend-item {
      background: transparent;
      border: 1.5px solid transparent;
    }
    
    .dunbar-legend-item:hover {
      background: rgba(0,0,0,0.03);
    }
    
    .dunbar-legend-item.selected {
      background: rgba(0,0,0,0.05);
      border-color: currentColor;
      border-radius: 9999px;
    }
    
    .dunbar-legend-item.selected span:first-child {
      transform: scale(1.2);
      box-shadow: 0 0 8px currentColor;
    }
    
    @keyframes dunbar-collapse {
      0% { transform: scale(1); opacity: 1; }
      50% { transform: scale(0.85); opacity: 0.7; }
      100% { transform: scale(0) translateY(-30px); opacity: 0; }
    }
    
    .dunbar-collapsing {
      animation: dunbar-collapse 0.7s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
    }
    
    /* Album Cover - Physics-based (handled by JS) */
    .album-cover-fading {
      animation: album-fade-to-interior 0.4s ease-out forwards;
    }
    
    @keyframes album-fade-to-interior {
      0% { opacity: 1; }
      100% { opacity: 0; }
    }
    
    /* Album cover will be controlled by spring physics in JS */
    #album-front-cover {
      touch-action: pan-y;
      user-select: none;
      -webkit-user-select: none;
    }
    
    /* Ink Drying Animation - mimics wet ink settling on paper */
    @keyframes ink-dry {
      0% {
        filter: brightness(1.3) contrast(0.8) saturate(0.7);
        opacity: 0.7;
      }
      30% {
        filter: brightness(1.15) contrast(0.9) saturate(0.85);
        opacity: 0.85;
      }
      60% {
        filter: brightness(1.05) contrast(0.95) saturate(0.95);
        opacity: 0.95;
      }
      100% {
        filter: brightness(1) contrast(1) saturate(1);
        opacity: 1;
      }
    }
    
    .ink-drying {
      animation: ink-dry 1.5s ease-out forwards;
    }
    
    /* Subtle ink shimmer during drying (wet ink reflection) */
    @keyframes ink-shimmer {
      0% {
        filter: brightness(1.25) contrast(0.85);
        transform: scale(1.002);
      }
      25% {
        filter: brightness(1.1) contrast(0.9);
        transform: scale(1.001);
      }
      50% {
        filter: brightness(1.15) contrast(0.88);
        transform: scale(1.0015);
      }
      75% {
        filter: brightness(1.05) contrast(0.95);
        transform: scale(1.0005);
      }
      100% {
        filter: brightness(1) contrast(1);
        transform: scale(1);
      }
    }
    
    .ink-drying-shimmer {
      animation: ink-shimmer 1.5s ease-out forwards;
    }
    
    .line-clamp-2 {
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
    
    /* Two-sided postcard styles */
    .postcard-container {
      margin: 0 auto;
    }
    
    .postcard-flipper {
      transform-style: preserve-3d;
    }
    
    .postcard-side {
      -webkit-backface-visibility: hidden;
      backface-visibility: hidden;
    }
    
    .postcard-front {
      /* Front face - no rotation, this shows by default */
    }
    
    .postcard-back {
      transform: rotateY(180deg);
      z-index: 2;
    }
    
    /* Ensure tap targets are accessible */
    .postcard-container button {
      -webkit-tap-highlight-color: transparent;
    }
    
    /* Mobile responsive postcard scaling */
    @media (max-width: 400px) {
      #message-preview .postcard-container,
      #final-preview .postcard-container {
        transform: scale(0.85);
        transform-origin: center center;
        margin: -15px -25px;
      }
    }
    
    @media (max-width: 360px) {
      #message-preview .postcard-container,
      #final-preview .postcard-container {
        transform: scale(0.75);
        transform-origin: center center;
        margin: -20px -40px;
      }
    }
    
    /* ═══════════════════════════════════════════════════════════════
       IMMERSIVE ANTHOLOGY VIEWER (Groupsake)
       ───────────────────────────────────────────────────────────────
       Same dark warm desk surface as the postcard immersive — each
       contribution gets its own moment instead of being one of many
       cramped onto a page. Tap the card to flip. Tap the brass arrows
       on screen edges (or swipe) to navigate between contributions.
       Audio play button — when a contributor left a voice note — sits
       at the bottom centre, big and obvious. Close lands back on the
       desk (curator) or threshold (recipient) based on context.
       ═══════════════════════════════════════════════════════════════ */
    #immersive-anthology-viewer {
      position: fixed; inset: 0; z-index: 10000;
      display: flex; flex-direction: column;
      /* Was opacity:0 → 1 with a 500ms transition (2026-05-22 removed).
         The transition put the viewer on its own composited layer while
         child <img> data-URIs were still decoding — Android Chrome
         stalled the card paint until the next interaction "woke" the
         layer. Showing the viewer instantly + relying on the inner
         card's natural fade keeps paint reliable. */
      touch-action: pan-y; overflow: hidden;
      -webkit-user-select: none; user-select: none;
    }

    /* Same warm desk surface used by the postcard immersive — keeps the
       two viewers feeling like a single product even though they have
       different cards inside. */
    .iav-desk {
      position: absolute; inset: 0;
      /* 2026-05-28 — centre pool warmed to candlelit amber to match the
         seal room (kept in sync with .ipv-desk). */
      background: radial-gradient(ellipse at 50% 38%, #241B12 0%, #16120D 50%, #0B0907 100%);
    }
    .iav-desk::before {
      content: '';
      position: absolute; inset: 0;
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='ditt'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.4' numOctaves='4' seed='18'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23ditt)'/%3E%3C/svg%3E");
      background-size: 200px;
      opacity: 0.05;
      mix-blend-mode: overlay;
      pointer-events: none;
    }
    /* A soft warm pendant from above — light catching the desk. Echoes
       the same vocabulary as the album-cover screen. */
    .iav-desk::after {
      content: '';
      position: absolute; inset: 0;
      background: radial-gradient(ellipse 70% 40% at 50% 0%, rgba(196,164,104,0.10) 0%, transparent 60%);
      pointer-events: none;
    }

    /* Close (top-right) — same chrome as postcard immersive */
    .iav-close-btn {
      position: fixed; top: 16px; right: 16px; z-index: 10004;
      width: 40px; height: 40px; border-radius: 50%;
      background: rgba(20,15,12,0.5);
      border: 1px solid rgba(255,255,255,0.18);
      display: flex; align-items: center; justify-content: center;
      cursor: pointer; transition: all 0.18s;
      box-shadow: 0 2px 10px rgba(0,0,0,0.35);
      backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
    }
    .iav-close-btn:active { transform: scale(0.92); background: rgba(255,255,255,0.12); }

    /* Tiny header — recipient + count. Whisper-quiet, not the hero. */
    .iav-header {
      position: fixed; top: 22px; left: 50%; transform: translateX(-50%);
      z-index: 10003;
      text-align: center;
      pointer-events: none;
    }
    .iav-kicker {
      font-family: 'Josefin Sans', sans-serif;
      font-size: 9px; letter-spacing: 0.35em; text-transform: uppercase;
      color: rgba(196, 164, 104, 0.45);
      margin: 0 0 4px;
    }
    .iav-recipient {
      font-family: 'Playfair Display', Georgia, serif;
      font-size: 14px; font-style: italic; font-weight: 500;
      color: rgba(240, 232, 216, 0.55);
      margin: 0;
    }

    /* Stage — fills viewport, centers the vertical letter card. */
    .iav-stage {
      flex: 1; position: relative;
      display: flex; align-items: center; justify-content: center;
      padding: 70px 18px 92px;
      z-index: 10001;
      overflow: hidden;
    }

    /* Vertical letter-card frame — width is locked to 320, height is
       set dynamically by iavRender() to match the current card's tier
       (300 / 460 / 580). JS applies a transform: scale() on top to fit
       the sized frame inside the viewport. The card renders DIRECTLY
       inside this frame — no flipper wrapper, no 3D properties anywhere
       (2026-05-22): the previous flipper-based rotateY approach used
       preserve-3d + backface-visibility which on some Android Chrome
       builds promoted the flipper to its own compositing layer where
       the first paint of innerHTML failed to land. The new 2D scaleX
       page-fold approach has zero compositor risk and looks identical. */
    .iav-card-frame {
      width: 320px;
      height: 460px;
      flex-shrink: 0;
      transform-origin: center center;
      transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                  height 0.42s cubic-bezier(0.22, 1, 0.36, 1);
    }

    /* Page-fold animation — 2D scaleX collapse around the LEFT edge
       (the book spine). The card compresses to nothing, content is
       swapped behind that veil, then the new card expands back from
       the same spine. Visually it reads like a page closing and
       opening on a hinge — same emotional vocabulary as the previous
       3D rotateY, but flat-2D and rock-solid on every browser. */
    .iav-card-frame > .la-letter-card,
    .iav-card-frame > .la-closing-card {
      transform-origin: left center;
      will-change: transform, opacity;
    }
    .iav-card-frame.iav-fold-out > .la-letter-card,
    .iav-card-frame.iav-fold-out > .la-closing-card {
      animation: iav-fold-out 0.30s cubic-bezier(0.55, 0, 0.55, 0.2) forwards;
    }
    .iav-card-frame.iav-fold-in > .la-letter-card,
    .iav-card-frame.iav-fold-in > .la-closing-card {
      animation: iav-fold-in 0.34s cubic-bezier(0.45, 0.8, 0.45, 1) forwards;
    }
    .iav-card-frame.iav-fold-out-back > .la-letter-card,
    .iav-card-frame.iav-fold-out-back > .la-closing-card {
      animation: iav-fold-out-back 0.30s cubic-bezier(0.55, 0, 0.55, 0.2) forwards;
      transform-origin: right center;
    }
    .iav-card-frame.iav-fold-in-back > .la-letter-card,
    .iav-card-frame.iav-fold-in-back > .la-closing-card {
      animation: iav-fold-in-back 0.34s cubic-bezier(0.45, 0.8, 0.45, 1) forwards;
      transform-origin: right center;
    }
    @keyframes iav-fold-out      { from { transform: scaleX(1); opacity: 1; } to { transform: scaleX(0.02); opacity: 0.55; } }
    @keyframes iav-fold-in       { from { transform: scaleX(0.02); opacity: 0.55; } to { transform: scaleX(1); opacity: 1; } }
    @keyframes iav-fold-out-back { from { transform: scaleX(1); opacity: 1; } to { transform: scaleX(0.02); opacity: 0.55; } }
    @keyframes iav-fold-in-back  { from { transform: scaleX(0.02); opacity: 0.55; } to { transform: scaleX(1); opacity: 1; } }

    /* Tap-pill — the primary navigation affordance. Sits at the bottom
       centre, brass-tinted to match the warm desk. Its copy adapts to
       the user's position: "Tap to turn" mid-book, "Tap to close" on
       the closing page. Tap-anywhere on the card itself ALSO triggers
       next, so the pill is a label/legibility aid as much as a button. */
    .iav-tap-pill {
      position: fixed; left: 50%; bottom: 70px; z-index: 10003;
      transform: translateX(-50%);
      display: inline-flex; align-items: center; gap: 8px;
      padding: 9px 18px 9px 16px;
      border-radius: 999px;
      border: 1px solid rgba(196, 164, 104, 0.30);
      background: linear-gradient(180deg, rgba(60,40,24,0.65), rgba(34,22,14,0.78));
      box-shadow: 0 6px 18px rgba(0,0,0,0.30), inset 0 1px 0 rgba(255,235,180,0.10);
      backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
      cursor: pointer;
      transition: transform 0.2s ease, opacity 0.25s ease;
      pointer-events: auto;
    }
    .iav-tap-pill:active { transform: translateX(-50%) scale(0.96); }
    .iav-tap-pill[disabled] { opacity: 0.4; pointer-events: none; }
    .iav-tap-pill-text {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-style: italic; font-size: 13.5px;
      color: rgba(240, 232, 216, 0.92);
      letter-spacing: 0.02em;
    }
    .iav-tap-pill-arrow {
      width: 22px; height: 22px; border-radius: 50%;
      background: radial-gradient(circle at 32% 26%, #F0CC82, #B88838 60%, #6B4A1A);
      box-shadow: inset 0 1px 0 rgba(255,235,180,0.45), 0 1px 3px rgba(60,40,20,0.25);
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0;
    }

    /* Subtle "back" affordance — small ghost chevron tucked to the
       lower-left for users who want to revisit a previous letter. Less
       prominent than the forward pill (linear reading is the default
       experience), but discoverable. */
    .iav-back-btn {
      position: fixed; left: 14px; bottom: 78px; z-index: 10003;
      width: 36px; height: 36px; border-radius: 50%;
      display: flex; align-items: center; justify-content: center;
      background: rgba(20,14,10,0.30);
      border: 1px solid rgba(196,164,104,0.16);
      cursor: pointer;
      transition: opacity 0.2s, transform 0.18s;
      opacity: 0.55;
      backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    }
    .iav-back-btn:hover { opacity: 1; }
    .iav-back-btn:active { transform: scale(0.92); }
    .iav-back-btn.iav-disabled { opacity: 0; pointer-events: none; }

    /* (Audio play CTA was a fixed bottom chrome button in v1; v2 moved
       audio playback INSIDE the card itself as a wax-seal pill so the
       letter holds everything. The old .iav-audio-btn rules were
       removed 2026-05-22.) */

    /* Navigation hint — appears briefly on the first letter so the
       recipient learns they can swipe or tap the arrows. Fades out on
       its own after a few seconds; the user shouldn't be told twice. */
    .iav-nav-hint {
      position: fixed; left: 50%; transform: translateX(-50%);
      bottom: 64px; z-index: 10002;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-style: italic; font-size: 12.5px;
      color: rgba(220, 190, 135, 0.48);
      letter-spacing: 0.04em;
      pointer-events: none;
      transition: opacity 0.6s ease;
    }
    .iav-nav-hint.iav-hidden { opacity: 0; }

    /* Page indicator — bottom centre, brass dots. Krug: tells the user
       where they are without making them count. Anderson: the dots
       quietly invite curiosity about what's next. */
    .iav-page-dots {
      position: fixed; bottom: 32px; left: 50%; transform: translateX(-50%);
      z-index: 10003;
      display: flex; align-items: center; gap: 6px;
      padding: 6px 12px; border-radius: 999px;
      background: rgba(20,14,10,0.45);
      backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    }
    .iav-page-dot {
      width: 6px; height: 6px; border-radius: 50%;
      background: rgba(196, 164, 104, 0.22);
      transition: all 0.25s ease;
    }
    .iav-page-dot.iav-page-dot-active {
      width: 18px; border-radius: 3px;
      background: rgba(220, 190, 135, 0.85);
    }

    /* Mobile layout — minimum side padding so the letter can fill the
       viewport. The JS scale-to-fit already centers the card. */
    @media (max-width: 520px) {
      .iav-stage { padding: 60px 12px 96px; }
      .iav-recipient { font-size: 13px; }
      .iav-tap-pill { bottom: 60px; padding: 8px 16px 8px 14px; }
      .iav-tap-pill-text { font-size: 13px; }
      .iav-back-btn { bottom: 66px; }
    }

    /* Respect reduced-motion preferences */
    @media (prefers-reduced-motion: reduce) {
      #immersive-anthology-viewer,
      .iav-card-frame,
      .iav-nav-btn,
      .iav-page-dot {
        transition-duration: 0.01ms !important;
      }
    }

    /* ═══ IMMERSIVE POSTCARD VIEWER ═══ */
    #immersive-postcard-viewer {
      position: fixed; inset: 0; z-index: 10000;
      display: flex; align-items: center; justify-content: center;
      opacity: 0; transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1);
      touch-action: none; overflow: hidden;
      -webkit-user-select: none; user-select: none;
    }
    #immersive-postcard-viewer.ipv-visible { opacity: 1; }
    
    /* Warm desk surface background — not harsh black.
       2026-05-28 — warmed the centre light-pool toward the seal room's
       candlelit tones and nudged grain up slightly, so the place a
       recipient opens a keepsake feels like the same room the curator
       sealed it in. Spotlight vignette preserved (no flat fill, no
       ruled lines — those belong on the seal "working desk" only). */
    .ipv-desk {
      position: absolute; inset: 0;
      background: radial-gradient(ellipse at 50% 40%, #241B12 0%, #16120D 50%, #0B0907 100%);
    }
    .ipv-desk::before {
      content: '';
      position: absolute; inset: 0;
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='dt'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.4' numOctaves='4' seed='12'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23dt)'/%3E%3C/svg%3E");
      background-size: 200px;
      opacity: 0.05;
      mix-blend-mode: overlay;
    }
    /* Soft warm pendant from above — light catching the desk. Mirrors
       the Groupsake viewer so both keepsake rooms share one light. */
    .ipv-desk::after {
      content: '';
      position: absolute; inset: 0;
      background: radial-gradient(ellipse 70% 40% at 50% 0%, rgba(196,164,104,0.09) 0%, transparent 60%);
      pointer-events: none;
    }
    
    /* Close button — subtle top-right */
    .ipv-close-btn {
      position: fixed; top: 16px; right: 16px; z-index: 10002;
      width: 40px; height: 40px; border-radius: 50%;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.08);
      display: flex; align-items: center; justify-content: center;
      cursor: pointer; transition: all 0.2s;
      backdrop-filter: blur(8px);
    }
    .ipv-close-btn:active { transform: scale(0.9); background: rgba(255,255,255,0.12); }

    /* Print button — sits next to the close button, identical chrome */
    .ipv-print-btn {
      position: fixed; top: 16px; right: 64px; z-index: 10002;
      width: 40px; height: 40px; border-radius: 50%;
      background: rgba(255,255,255,0.06);
      border: 1px solid rgba(255,255,255,0.08);
      display: flex; align-items: center; justify-content: center;
      cursor: pointer; transition: all 0.2s;
      backdrop-filter: blur(8px);
    }
    .ipv-print-btn:active { transform: scale(0.9); background: rgba(255,255,255,0.12); }
    /* Letter receive viewer — print button sits next to its close button */
    .lt-recv-print-btn {
      position: fixed; top: 12px; right: 58px; z-index: 10001;
      width: 36px; height: 36px; border-radius: 50%;
      background: rgba(60,40,20,0.45); border: none; cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      backdrop-filter: blur(4px);
    }
    .lt-recv-print-btn:active { transform: scale(0.92); background: rgba(60,40,20,0.6); }

    /* ═══ PRINT KEEPSAKES ═══════════════════════════════════════════════
       One-click print for postcards and letters. The .petra-print-root
       container is invisible on screen and the only thing visible in print.
       Browser's native dialog handles printer + Save-as-PDF on every
       platform. */
    .petra-print-root {
      display: none;
      position: fixed; top: 0; left: 0;
      width: 100%; pointer-events: none;
    }
    @media print {
      @page { margin: 0; size: letter; }
      body > * { display: none !important; }
      .petra-print-root {
        display: block !important;
        position: static !important;
        width: 100% !important;
        height: auto !important;
        background: white !important;
        margin: 0 !important;
        padding: 0 !important;
      }

      /* ─── Print-root universal defenses ───
         These apply to every descendant of the print root and defeat
         the five things that cause "content missing" in browser print:
         1. mix-blend-mode (lifts element to a compositing layer that
            the print rasterizer can silently drop).
         2. CSS mask / -webkit-mask (deckled paper edges render blank
            or destroy the masked element in Chromium print).
         3. CSS filter (drop-shadow / brightness / contrast — same
            compositing-layer problem as mix-blend-mode).
         4. Lingering animation / transition state that may leave
            opacity at 0 or a transform that displaces content offscreen.
         5. Pseudo-elements (::before / ::after) inheriting the same
            blend / mask / filter issues. */
      .petra-print-root,
      .petra-print-root *,
      .petra-print-root *::before,
      .petra-print-root *::after {
        mix-blend-mode: normal !important;
        -webkit-mask-image: none !important;
        mask-image: none !important;
        animation: none !important;
        transition: none !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
      }
      /* Filter is allowed on the root, but stripped from descendants —
         the `drop-shadow` on .lt-page would otherwise drop the entire
         page into a compositing layer. */
      .petra-print-root * {
        filter: none !important;
      }

      /* Each page fills a Letter sheet exactly */
      .petra-print-page {
        width: 8.5in; height: 11in;
        display: flex; align-items: center; justify-content: center;
        page-break-after: always;
        background: white;
        overflow: hidden;
        margin: 0 auto;
      }
      .petra-print-page:last-child { page-break-after: auto; }

      /* POSTCARD — 6×4" centered on the Letter sheet. The renderPostcard
         output ships both faces in one flipper element; we hide one face
         per page and remove the rotateY so each face prints flat. */
      .petra-print-page--postcard .petra-print-postcard-wrap {
        position: relative;
        width: 6in; height: 4in;
      }
      .petra-print-page--postcard .petra-print-postcard-wrap > * {
        width: 100% !important;
        height: 100% !important;
        margin: 0 !important;
        max-width: none !important;
      }
      .petra-print-page--postcard .postcard-front,
      .petra-print-page--postcard .postcard-back {
        position: relative !important;
        width: 100% !important;
        height: 100% !important;
        transform: none !important;
        backface-visibility: visible !important;
        -webkit-backface-visibility: visible !important;
      }
      /* Hide the face we don't want on each page (set inline via JS) */
      .petra-print-postcard-wrap[data-face="front"] .postcard-back { display: none !important; }
      .petra-print-postcard-wrap[data-face="back"]  .postcard-front { display: none !important; }

      /* LETTER — each .lt-page on its own sheet at full Letter size,
         with 0.5" margin. Strips shadows, animations, and any
         decorative drop-shadows from screen rendering. */
      .petra-print-letter .lt-page {
        page-break-after: always;
        margin: 0 auto !important;
        width: 7.5in !important;
        max-width: none !important;
        min-height: 10in !important;
        padding: 0.5in !important;
        box-shadow: none !important;
        border-radius: 0 !important;
        filter: none !important;
        background-clip: padding-box !important;
      }
      .petra-print-letter .lt-page:last-child { page-break-after: auto; }
      .petra-print-letter .lt-canvas,
      .petra-print-letter .lt-page-wrap {
        background: none !important;
        padding: 0 !important;
      }

      /* Preserve colors on all printed surfaces — without this, browsers
         strip backgrounds to save ink, washing the cream paper to white. */
      * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
      }
    }

    /* The postcard stage — starts vertical, transitions to landscape */
    .ipv-stage {
      position: relative;
      transform-style: preserve-3d;
      perspective: 1800px;
      background: transparent;
      will-change: transform;
      transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), width 0.9s cubic-bezier(0.22, 1, 0.36, 1), height 0.9s cubic-bezier(0.22, 1, 0.36, 1);
    }

    /* Immersive-only edge guard: prevents sub-pixel light leaks at the card edge. */
    #ipv-card-container {
      position: relative;
      width: 100%;
      height: 100%;
      transform-style: preserve-3d;
      border-radius: 7px;
      background: #0f0c0a;
      isolation: isolate;
    }
    #ipv-card-container::before {
      content: '';
      position: absolute;
      inset: -1px;
      border-radius: inherit;
      background: #0f0c0a;
      pointer-events: none;
      z-index: -1;
    }
    #ipv-card-container .postcard-container,
    #ipv-card-container .postcard-flipper {
      width: 100%;
      height: 100%;
      margin: 0;
    }
    #ipv-card-container .postcard-side {
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-clip: border-box;
      transform: translateZ(0);
    }
    #ipv-card-container .postcard-back {
      transform: rotateY(180deg) translateZ(0);
    }
    
    /* Phase 1: Card enters with NO rotation — vertical, matching phone orientation */
    /* Phase 2: .ipv-rotated class adds the rotation after a delay */
    @media (orientation: portrait) {
      .ipv-stage.ipv-rotated {
        transform: rotate(90deg);
      }
    }
    
    /* Rotate phone prompt — appears during the transition */
    .ipv-rotate-prompt {
      position: fixed; z-index: 10001;
      bottom: 32px; left: 50%; transform: translateX(-50%);
      display: flex; align-items: center; gap: 10px;
      padding: 12px 24px;
      border-radius: 28px;
      background: rgba(255,248,236,0.08);
      border: 1px solid rgba(239,217,199,0.1);
      backdrop-filter: blur(12px);
      opacity: 0;
      transition: opacity 0.6s ease;
      pointer-events: none;
    }
    .ipv-rotate-prompt.ipv-prompt-visible { opacity: 1; }
    .ipv-rotate-prompt .ipv-rotate-icon {
      animation: ipvPhoneRotate 1.8s ease-in-out infinite;
    }
    .ipv-rotate-prompt .ipv-rotate-text {
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 14px; font-style: italic; font-weight: 500;
      color: rgba(239,217,199,0.5);
      letter-spacing: 0.02em;
    }
    @keyframes ipvPhoneRotate {
      0%, 100% { transform: rotate(0deg); }
      40% { transform: rotate(-90deg); }
      60% { transform: rotate(-90deg); }
    }
    
    /* The flipper container — spring physics feel */
    .ipv-flipper {
      position: relative;
      width: 100%; height: 100%;
      transform-style: preserve-3d;
      transition: transform 0.65s cubic-bezier(0.25, 1.15, 0.4, 1);
      cursor: pointer;
    }
    .ipv-flipper.ipv-flipped { transform: rotateY(180deg); }
    
    /* Front and back faces — rich paper depth */
    .ipv-face {
      position: absolute; inset: 0;
      -webkit-backface-visibility: hidden;
      backface-visibility: hidden;
      border-radius: 6px;
      overflow: hidden;
      /* Stacked paper shadow — each layer adds depth like real card stock */
      box-shadow:
        0 1px 0 rgba(210,195,170,0.5),
        0 2px 0 rgba(195,175,150,0.4),
        0 3px 0 rgba(175,158,130,0.3),
        0 4px 0 rgba(160,142,115,0.2),
        0 8px 16px rgba(0,0,0,0.25),
        0 16px 32px rgba(0,0,0,0.2),
        0 32px 64px rgba(0,0,0,0.15),
        0 48px 96px rgba(0,0,0,0.1);
    }
    /* Paper edge texture on face */
    .ipv-face::after {
      content: '';
      position: absolute; inset: 0;
      border-radius: 6px;
      box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
      pointer-events: none;
    }
    .ipv-back { transform: rotateY(180deg); }
    
    /* Ambient warmth beneath the card — like desk lamp glow */
    .ipv-glow {
      position: absolute; 
      width: 120%; height: 120%;
      top: -10%; left: -10%;
      border-radius: 50%;
      background: radial-gradient(ellipse, rgba(241,189,120,0.04) 0%, transparent 60%);
      filter: blur(40px);
      pointer-events: none; z-index: -1;
    }
    
    /* Hints — Seductive micro-interaction design (Stephen Anderson)
       The hint should feel like discovering a secret, not reading instructions.
       It appears as a gentle breath on the card — a subtle shimmer that says
       "there's more here" without ever telling you what to do. */
    
    .ipv-flip-hint {
      position: fixed; z-index: 10001;
      pointer-events: none;
      display: flex; align-items: center; gap: 6px;
      padding: 8px 16px;
      border-radius: 20px;
      background: rgba(0,0,0,0.35);
      border: 1px solid rgba(255,255,255,0.08);
      backdrop-filter: blur(16px);
      -webkit-backdrop-filter: blur(16px);
      bottom: 28px; left: 50%; transform: translateX(-50%);
      transition: opacity 1.2s cubic-bezier(0.22, 1, 0.36, 1), transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), bottom 0.9s cubic-bezier(0.22, 1, 0.36, 1), right 0.9s cubic-bezier(0.22, 1, 0.36, 1);
    }
    /* When card has rotated to landscape in portrait mode */
    @media (orientation: portrait) {
      .ipv-flip-hint.ipv-hint-rotated {
        bottom: auto; left: auto;
        right: 16px; top: 50%; 
        transform: translateY(-50%) rotate(90deg);
      }
    }
    
    .ipv-flip-hint .ipv-hint-icon {
      width: 16px; height: 16px;
      animation: ipvHintBreath 2.8s ease-in-out infinite;
    }
    .ipv-flip-hint .ipv-hint-text {
      font-family: 'DM Sans', sans-serif;
      font-size: 11px; font-weight: 500;
      color: rgba(255,255,255,0.85);
      letter-spacing: 0.04em;
    }
    .ipv-flip-hint .ipv-hint-arrow {
      animation: ipvHintNudge 2.8s ease-in-out infinite;
      opacity: 0.5;
    }
    
    /* The icon breathes — subtly pulses to draw the eye without demanding it */
    @keyframes ipvHintBreath {
      0%, 100% { opacity: 0.4; transform: rotateY(0deg); }
      50% { opacity: 0.7; transform: rotateY(20deg); }
    }
    /* A tiny rightward nudge — the suggestion of turning */
    @keyframes ipvHintNudge {
      0%, 100% { transform: translateX(0); }
      50% { transform: translateX(3px); }
    }
    
    .ipv-close-hint {
      position: fixed; z-index: 10001;
      pointer-events: none;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px; font-style: italic;
      color: rgba(239,217,199,0.12);
      top: 20px; left: 50%; transform: translateX(-50%);
      transition: opacity 1.2s ease, transform 0.9s ease, top 0.9s ease, left 0.9s ease;
    }
    @media (orientation: portrait) {
      .ipv-close-hint.ipv-hint-rotated {
        top: 50%; left: 20px;
        transform: translateY(-50%) rotate(90deg);
      }
    }
    
    /* Entry animation — card lifts up vertically (matching phone orientation) */
    .ipv-card-enter {
      animation: ipvCardEnter 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    @keyframes ipvCardEnter {
      0% { transform: scale(0.3) translateY(60px) translateZ(-200px) rotateX(8deg); opacity: 0; filter: blur(4px); }
      50% { filter: blur(0); }
      100% { transform: scale(1) translateY(0) translateZ(0) rotateX(0); opacity: 1; filter: blur(0); }
    }
    
    /* Subtle edge shimmer — appears after card settles in landscape to hint at flippability */
    .ipv-stage.ipv-rotated::after,
    .ipv-stage:not(.ipv-rotated)::after {
      content: '';
      position: absolute;
      top: 0; right: -2px; bottom: 0; width: 4px;
      background: linear-gradient(180deg, transparent 10%, rgba(255,248,236,0.15) 30%, rgba(255,248,236,0.25) 50%, rgba(255,248,236,0.15) 70%, transparent 90%);
      border-radius: 0 6px 6px 0;
      opacity: 0;
      animation: ipvEdgeShimmer 3s ease-in-out 2.5s 2;
      pointer-events: none;
      z-index: 5;
    }
    @keyframes ipvEdgeShimmer {
      0%, 100% { opacity: 0; }
      30% { opacity: 1; }
      70% { opacity: 1; }
    }
    @media (orientation: portrait) {
      .ipv-stage::after {
        top: -2px; right: 0; left: 0; bottom: auto;
        width: auto; height: 4px;
        background: linear-gradient(90deg, transparent 10%, rgba(255,248,236,0.15) 30%, rgba(255,248,236,0.25) 50%, rgba(255,248,236,0.15) 70%, transparent 90%);
        border-radius: 6px 6px 0 0;
      }
    }

    /* ═══════════════════════════════════════════════════════
       LEGACY ANTHOLOGY — Legend-Tier Groupsake
    ═══════════════════════════════════════════════════════ */
    @keyframes la-cover-breathe {
      0%, 100% { box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 32px 64px rgba(0,0,0,0.25); }
      50% { box-shadow: 0 10px 40px rgba(0,0,0,0.45), 0 36px 72px rgba(0,0,0,0.3); }
    }
    @keyframes la-latch-gleam {
      0%, 100% { filter: brightness(1); }
      50% { filter: brightness(1.15); }
    }
    @keyframes la-latch-hint-pulse {
      0%, 100% { transform: translateY(0) scale(1); }
      50% { transform: translateY(-2px) scale(1.04); }
    }
    .la-latch {
      animation: la-latch-gleam 3s ease-in-out infinite, la-latch-hint-pulse 2.5s ease-in-out infinite;
    }
    @keyframes la-cover-open {
      0% { transform: perspective(2000px) rotateY(0deg); }
      100% { transform: perspective(2000px) rotateY(-165deg); }
    }
    .la-cover-opening {
      animation: la-cover-open 1.8s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }
    @keyframes la-ink-life-bleed {
      0% { filter: brightness(1.35) contrast(0.75) saturate(0.6); opacity: 0.3; transform: scale(1.004); }
      30% { filter: brightness(1.15) contrast(0.88) saturate(0.8); opacity: 0.75; }
      100% { filter: brightness(1) contrast(1.05) saturate(1); opacity: 1; transform: scale(1); }
    }
    .la-ink-symphony {
      animation: la-ink-life-bleed var(--ink-dry-duration) var(--ease-settle) forwards;
    }
    /* The PRESS: from the floating ready-state, the wax presses down and
       SQUASHES on contact (scaleX up / scaleY down), rebounds, then settles —
       so it feels stamped onto the paper. No `filter` here on purpose: it would
       clobber the disc's inline drop-shadow. */
    @keyframes la-wax-seal-drop {
      0%   { transform: translateY(-4px) scale(1.05); opacity: 0.62; }
      38%  { transform: translateY(3px) scale(1.08, 0.88); opacity: 1; }
      62%  { transform: translateY(0) scale(0.985, 1.025); opacity: 1; }
      100% { transform: translateY(0) scale(1); opacity: 1; }
    }
    .la-wax-dropping {
      transform-origin: 50% 58%;
      animation: la-wax-seal-drop 0.72s cubic-bezier(0.3, 1.3, 0.4, 1) forwards;
    }
    /* Splatter beads — wax squeezed out at the rim. Hidden until the press,
       then each pops from its own centre (staggered via inline delays). */
    @keyframes la-wax-splat {
      0%   { opacity: 0; transform: scale(0); }
      55%  { opacity: 1; transform: scale(1.3); }
      100% { opacity: 0.9; transform: scale(1); }
    }
    .la-wax-splat-blob { opacity: 0; transform-box: fill-box; transform-origin: center; }
    .la-wax-dropping .la-wax-splat-blob { animation: la-wax-splat 0.5s cubic-bezier(0.34, 1.56, 0.5, 1) forwards; }
    @keyframes la-card-arrive {
      0% { opacity: 0; transform: translateY(40px) rotate(calc(var(--card-rotation, 0deg) * 3)) scale(0.85); }
      60% { opacity: 1; transform: translateY(-4px) rotate(calc(var(--card-rotation, 0deg) * 0.8)) scale(1.02); }
      100% { opacity: 1; transform: translateY(0) rotate(var(--card-rotation, 0deg)) scale(1); }
    }
    .la-card-entering {
      animation: la-card-arrive 0.7s var(--ease-settle) forwards;
      animation-delay: var(--card-delay, 0s);
      opacity: 0;
    }
    @keyframes la-wax-cta-pulse {
      0%, 100% { box-shadow: 0 0 0 0 rgba(139,32,32,0.4), 0 4px 16px rgba(139,32,32,0.2); }
      50% { box-shadow: 0 0 0 12px rgba(139,32,32,0), 0 6px 20px rgba(139,32,32,0.3); }
    }
    .la-wax-cta { animation: la-wax-cta-pulse 2.5s ease-in-out infinite; }

    /* 2026-05-27 — Desk empty-state envelope. Gently rocks like a letter
       waiting on the desk to be opened. Three-second cycle so it's
       perceptible but never frenetic. */
    @keyframes la-await-rock {
      0%, 100% { transform: translateY(0) rotate(-1.4deg); }
      50%      { transform: translateY(-3px) rotate(1.6deg); }
    }
    .la-await-envelope { animation: la-await-rock 3.6s ease-in-out infinite; transform-origin: 50% 80%; }
    /* Fade the whole block in once when the desk first renders empty. */
    @keyframes la-empty-fade-in {
      0%   { opacity: 0; transform: translateY(8px); }
      100% { opacity: 1; transform: translateY(0); }
    }
    .la-empty-await { animation: la-empty-fade-in 0.6s var(--ease-settle) forwards; }
    /* Seal CTA — subtle aura breath so the climactic action draws the eye
       without becoming a flashing button. */
    @keyframes la-seal-aura-breathe {
      0%, 100% { box-shadow: 0 0 0 0 rgba(196,164,104,0); }
      50%      { box-shadow: 0 0 0 22px rgba(196,164,104,0.04), 0 0 36px 4px rgba(196,164,104,0.10); }
    }
    .la-seal-cta { border-radius: 50%; animation: la-seal-aura-breathe 4.2s ease-in-out infinite; }
    /* Wax disc — pre-seal "ready to be pressed" state. Reduced opacity so
       it reads as floating-above-paper, and a slow lift so it feels
       suspended rather than landed. The wax-dropping animation (added on
       seal confirm) snaps it into place with full opacity. */
    @keyframes la-wax-float {
      0%, 100% { transform: translateY(0); }
      50%      { transform: translateY(-4px); }
    }
    .la-wax-ready {
      opacity: 0.62;
      animation: la-wax-float 3.4s ease-in-out infinite;
    }
    /* When the seal is committed, .la-wax-sealed replaces .la-wax-ready —
       the float stops, the disc lands at full opacity, and the cast
       shadow tightens against the paper. */
    .la-wax-sealed {
      opacity: 1;
      animation: none;
      transform: translateY(0);
    }
    .la-flip-scene { perspective: 1200px; }
    .la-flip-card {
      position: relative; transform-style: preserve-3d;
      transition: transform 0.8s var(--ease-settle);
    }
    .la-flip-card.flipped { transform: rotateY(180deg); }
    .la-flip-face {
      position: absolute; inset: 0; backface-visibility: hidden;
      -webkit-backface-visibility: hidden; border-radius: 5px; overflow: hidden;
    }
    .la-flip-back { transform: rotateY(180deg); }
    .la-corner-curl::after {
      content: ''; position: absolute; bottom: 0; right: 0;
      width: 60px; height: 60px;
      background: linear-gradient(225deg, rgba(244,239,231,0.95) 0%, rgba(244,239,231,0.9) 35%, rgba(220,210,195,0.7) 50%, transparent 50.5%);
      background-position: bottom right; background-repeat: no-repeat; background-size: 0 0;
      border-radius: 0 0 5px 0;
      animation: corner-curl-hint 2.8s var(--ease-settle) 2s 2;
      pointer-events: none; z-index: 15;
    }
    @keyframes la-toast-in {
      0% { transform: translateY(20px) translateX(-50%); opacity: 0; }
      100% { transform: translateY(0) translateX(-50%); opacity: 1; }
    }
    @keyframes la-toast-out {
      0% { opacity: 1; }
      100% { opacity: 0; transform: translateY(-10px) translateX(-50%); }
    }
    .la-toast { animation: la-toast-in 0.4s var(--ease-settle) forwards; }
    .la-toast.hiding { animation: la-toast-out 0.3s ease forwards; }

    /* ═══ ARCHIVE LETTER — The Continental Aerogram ═══ */
    .archive-letter {
      perspective: 1500px;
      transform-style: preserve-3d;
      position: relative;
      width: 320px; max-width: 100%;
      margin: 0 auto;
    }
    .archive-letter-body {
      position: relative;
      background: var(--al-paper, #E3F2FD);
      border-radius: 1px;
      box-shadow: 0 8px 30px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.04);
    }
    /* Onionskin cockle texture */
    .archive-letter-body::before {
      content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
      opacity: 0.06; mix-blend-mode: multiply;
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='onion'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='5' seed='18'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23onion)'/%3E%3C/svg%3E");
      background-size: 150px;
    }
    /* Diamond grid watermark */
    .archive-letter-body::after {
      content: ''; position: absolute; inset: 6px; z-index: 0; pointer-events: none;
      opacity: 0.035;
      background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, currentColor 8px, currentColor 8.5px),
                         repeating-linear-gradient(-45deg, transparent, transparent 8px, currentColor 8px, currentColor 8.5px);
    }
    /* Airmail border strips */
    .al-border-top, .al-border-bottom {
      position: absolute; left: 0; right: 0; height: 6px; z-index: 5;
      background: repeating-linear-gradient(
        -55deg,
        var(--al-stripe1, #cc3333) 0px, var(--al-stripe1, #cc3333) 6px,
        #ffffff 6px, #ffffff 12px,
        var(--al-stripe2, #336699) 12px, var(--al-stripe2, #336699) 18px,
        #ffffff 18px, #ffffff 24px
      );
    }
    .al-border-top { top: 0; border-radius: 1px 1px 0 0; }
    .al-border-bottom { bottom: 0; border-radius: 0 0 1px 1px; }

    /* Flap panels */
    .al-flap {
      position: absolute; left: 0; right: 0; z-index: 10;
      background: var(--al-paper, #E3F2FD);
      transform-style: preserve-3d;
      backface-visibility: visible;
      transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
      box-shadow: 0 2px 6px rgba(0,0,0,0.06);
    }
    .al-flap-top {
      top: 0; height: 33.33%;
      transform-origin: bottom center;
      border-radius: 1px 1px 0 0;
    }
    .al-flap-top.open { transform: rotateX(-178deg); }
    .al-flap-bottom {
      bottom: 0; height: 33.33%;
      transform-origin: top center;
      border-radius: 0 0 1px 1px;
    }
    .al-flap-bottom.open { transform: rotateX(178deg); }
    /* Crease line */
    .al-flap::after {
      content: ''; position: absolute; left: 8px; right: 8px; height: 1px;
      background: linear-gradient(90deg, transparent, rgba(0,0,0,0.06), transparent);
    }
    .al-flap-top::after { bottom: 0; }
    .al-flap-bottom::after { top: 0; }

    /* Pull tab breathing animation */
    @keyframes al-tab-breathe {
      0%, 100% { transform: translateX(-50%) translateY(0); }
      50% { transform: translateX(-50%) translateY(-3px); }
    }
    .al-pull-tab {
      position: absolute; left: 50%; transform: translateX(-50%);
      width: 40px; height: 14px; border-radius: 0 0 6px 6px;
      background: linear-gradient(180deg, var(--al-paper, #E3F2FD), rgba(0,0,0,0.04));
      box-shadow: 0 2px 4px rgba(0,0,0,0.08);
      animation: al-tab-breathe 2.5s ease-in-out infinite;
      cursor: grab; z-index: 15; touch-action: none;
    }

    /* Brass date stamp */
    @keyframes al-stamp-press {
      0% { transform: translateY(-40px) rotate(-5deg) scale(1.3); opacity: 0; }
      60% { transform: translateY(2px) rotate(1deg) scale(0.98); opacity: 1; }
      100% { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; }
    }
    .al-date-stamp {
      opacity: 0;
      font-family: 'Courier New', Courier, monospace;
      font-weight: 700; font-size: 10px; letter-spacing: 0.08em;
      text-transform: uppercase; color: rgba(139,69,19,0.5);
      border: 1.5px solid rgba(139,69,19,0.3);
      padding: 3px 8px; border-radius: 2px;
      transform: rotate(-3deg);
    }
    .al-date-stamp.stamped {
      animation: al-stamp-press 0.4s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    }

    /* Typewriter font for envelope back */
    .al-typewriter {
      font-family: 'Courier New', Courier, monospace;
      font-weight: 400; letter-spacing: 0.02em;
      color: rgba(0,0,0,0.65);
    }

    /* Paper stock options */
    .al-stock-azure { --al-paper: #E3F2FD; --al-stripe1: #cc3333; --al-stripe2: #336699; color: #336699; }
    .al-stock-manila { --al-paper: #F3E5AB; --al-stripe1: #8B4513; --al-stripe2: #cc3333; color: #8B4513; }
    .al-stock-vellum { --al-paper: #F8F9FA; --al-stripe1: #2A9D8F; --al-stripe2: #ffffff; color: #4a5868; }

    /* ═══ HOT-FOIL STAMPING — debossed title preview ═══ */
    .la-foil-preview {
      font-family: 'Playfair Display', Georgia, serif;
      font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
      color: transparent;
      -webkit-background-clip: text; background-clip: text;
      background-image: linear-gradient(168deg, rgba(61,40,21,0.45) 0%, rgba(61,40,21,0.35) 100%);
      text-shadow: 0 1.5px 0 rgba(255,220,180,0.4), 0 -0.5px 0 rgba(30,20,10,0.15);
      transition: opacity 0.3s, letter-spacing 0.5s var(--ease-settle);
    }

    /* ═══ PROMPT CARDS — torn paper scraps ═══ */
    .la-prompt-card {
      position: relative; padding: 10px 14px;
      background: linear-gradient(175deg, #FFFDF5, #F5F0E6);
      border-radius: 1px;
      box-shadow: 0 1px 3px rgba(60,40,20,0.12), 1px 2px 6px rgba(60,40,20,0.06);
      cursor: pointer; transition: transform 0.3s var(--ease-settle), opacity 0.3s;
    }
    .la-prompt-card::before {
      content: ''; position: absolute; top: -2px; left: 0; right: 0; height: 4px;
      background: linear-gradient(90deg, #F5F0E6 0%, #EDE7DA 20%, #F5F0E6 40%, #EDE7DA 60%, #F5F0E6 80%, #EDE7DA 100%);
      clip-path: polygon(0% 60%, 3% 20%, 7% 70%, 12% 30%, 18% 80%, 23% 10%, 28% 60%, 35% 25%, 40% 75%, 48% 15%, 53% 65%, 60% 30%, 67% 80%, 73% 20%, 80% 60%, 87% 35%, 93% 70%, 97% 25%, 100% 55%, 100% 100%, 0% 100%);
    }
    .la-prompt-card:hover { transform: translateY(-2px) rotate(0deg) !important; }

    /* ═══ LIVING LEDGER — pencil to ink transition ═══ */
    .la-ledger-pending {
      color: #C4BAA8; font-style: italic;
      text-decoration: none;
      position: relative;
    }
    .la-ledger-pending::after {
      content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 1px;
      background: repeating-linear-gradient(90deg, #C4BAA8 0px, #C4BAA8 2px, transparent 2px, transparent 4px);
      opacity: 0.4;
    }
    .la-ledger-done {
      color: #3a3428; font-weight: 600; font-style: normal;
      transition: color 0.6s, font-weight 0.3s;
    }

    /* ═══ BRASS SLIDE — horizontal drag to unlock ═══ */
    .la-slide-track {
      position: relative; width: 100%; height: 48px;
      border-radius: 24px; overflow: hidden;
      background: rgba(255,250,245,0.06);
      border: 1px solid rgba(196,164,104,0.15);
    }
    .la-slide-fill {
      position: absolute; top: 0; left: 0; bottom: 0; width: 0;
      background: linear-gradient(90deg, rgba(196,164,104,0.08), rgba(196,164,104,0.15));
      border-radius: 24px; transition: width 0.05s;
    }
    .la-slide-handle {
      position: absolute; top: 3px; left: 3px;
      width: 42px; height: 42px; border-radius: 50%;
      background: linear-gradient(145deg, #C4A468, #A88C50 40%, #8A7430);
      box-shadow: 0 2px 8px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,240,180,0.4);
      display: flex; align-items: center; justify-content: center;
      cursor: grab; touch-action: none; z-index: 2;
      transition: box-shadow 0.2s;
    }
    .la-slide-handle:active { cursor: grabbing; box-shadow: 0 1px 4px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,240,180,0.4); }
    .la-slide-text {
      position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
      font-family: 'Cormorant Garamond', Georgia, serif;
      font-size: 12px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
      color: rgba(196,164,104,0.35); pointer-events: none;
      transition: opacity 0.3s;
    }
  