/* ============================================================
   Dashboard (redesign) - /dashboard-new
   Self-contained styles for the new couple dashboard layout.
   Tokens are scoped to .dnew so they don't leak into the rest
   of the site. Imported design: claude.ai/design "Dashboard".
   ============================================================ */

/* Outfit @font-face and the shared header/chrome rules used to live here,
   scoped to body.dashboard-new-page. They now sit in css/site-chrome.css,
   which header.php loads on every non-admin page - keeping two copies in
   step was never going to happen. Only the page-level body font stays,
   because Outfit below the header is specific to the redesigned pages. */
body.dashboard-new-page {
  font-family: "Outfit", "Inter", -apple-system, "Helvetica Neue", sans-serif;
}

/* ============================================================
   Tokens (scoped)
   ============================================================ */
.dnew {
  --sage:            #8B9D83;
  --sage-dark:       #6B7D63;
  --sage-light:      #A8B9A0;
  --sage-wash:       #E8EDE4;
  --sage-mist:       #F1F4EE;

  --off-white:       #F5F3F0;
  --soft-bg:         #FEFDFB;
  --paper:           #FFFFFF;

  --charcoal:        #2C2C2C;
  --charcoal-soft:   #4A4A4A;
  --muted:           #7A7A7A;
  --hairline:        #E5E2DC;
  --hairline-soft:   #EFECE6;

  --fg-1:            var(--charcoal);
  --fg-2:            var(--charcoal-soft);
  --fg-3:            var(--muted);

  --border:          var(--hairline);
  --border-soft:     var(--hairline-soft);

  --font-display:    "Playfair Display", "Cormorant Garamond", Georgia, serif;
  --font-body:       "Outfit", "Inter", -apple-system, "Helvetica Neue", sans-serif;

  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  --shadow-xs:  0 1px 2px rgba(44, 44, 44, 0.04);
  --shadow-sm:  0 2px 6px rgba(44, 44, 44, 0.05), 0 1px 2px rgba(44, 44, 44, 0.04);
  --shadow-md:  0 8px 24px rgba(44, 44, 44, 0.07), 0 2px 4px rgba(44, 44, 44, 0.04);
  --shadow-lg:  0 18px 48px rgba(44, 44, 44, 0.10), 0 4px 10px rgba(44, 44, 44, 0.05);
  --shadow-sage: 0 10px 30px rgba(107, 125, 99, 0.18);

  --ease-out:  cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-fast:  120ms;
  --dur-base:  220ms;
  --dur-slow:  420ms;

  background: var(--off-white);
  color: var(--fg-1);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

/* The dashboard owns the page background while active */
body.dashboard-new-page { background: var(--off-white); }

.dnew *, .dnew *::before, .dnew *::after { box-sizing: border-box; }

/* ============================================================
   Shared primitives
   ============================================================ */
.dnew .dnew-wrap { max-width: 1180px; margin: 0 auto; padding: 36px 32px 80px; }

.dnew h1, .dnew h2, .dnew h3, .dnew h4 {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--fg-1);
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0;
}
.dnew h3 { line-height: 1.25; }
.dnew p { margin: 0; color: var(--fg-2); line-height: 1.55; }

.dnew .eyebrow {
  font-family: var(--font-body);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--fg-3);
  font-weight: 500;
}
.dnew .caption { font-size: 14px; color: var(--fg-3); line-height: 1.5; }
.dnew .lede { font-size: 20px; line-height: 1.55; color: var(--fg-2); }

.dnew .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-body);
  font-size: 16px; font-weight: 500;
  padding: 12px 22px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.dnew .btn:active { transform: translateY(1px) scale(0.99); }
.dnew .btn--primary { background: var(--sage); color: var(--soft-bg); box-shadow: var(--shadow-sage); }
.dnew .btn--secondary { background: transparent; color: var(--charcoal); border-color: var(--border); }
.dnew .btn--ghost { background: transparent; color: var(--sage-dark); }
.dnew .btn svg { width: 18px; height: 18px; }

@media (hover: hover) and (pointer: fine) {
  .dnew .btn--primary:hover { background: var(--sage-dark); }
  .dnew .btn--secondary:hover { background: var(--sage-mist); border-color: var(--sage-light); }
  .dnew .btn--ghost:hover { background: var(--sage-wash); }
}

/* generic elevated card hover */
.dnew .gg-card { transition: box-shadow var(--dur-base) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .dnew .gg-card:hover { box-shadow: var(--shadow-md); }
}

.dnew a.dnew-plain { text-decoration: none; color: inherit; border-bottom: none; }

/* ============================================================
   Onboarding panel
   ============================================================ */
.dnew-onboard {
  position: relative;
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-left: 5px solid var(--sage);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 20px 24px 22px;
  margin-bottom: 28px;
}
.dnew-onboard-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; padding-right: 30px;   /* clear the corner dismiss button */
}
.dnew-onboard-headleft { display: flex; align-items: center; gap: 14px; min-width: 0; flex: 1; }
.dnew-onboard-icon { display: none; }   /* sparkle removed from the onboarding panel */
.dnew-onboard-title { font-size: 18px; font-weight: 600; color: var(--charcoal); line-height: 1.25; }
.dnew-onboard-progress { display: flex; align-items: center; gap: 14px; flex: none; }
.dnew-progress-track {
  width: 120px; height: 6px; border-radius: var(--radius-pill);
  background: var(--paper); overflow: hidden;
}
.dnew-progress-fill {
  height: 100%; background: var(--sage); border-radius: var(--radius-pill);
  transition: width var(--dur-slow) var(--ease-out);
}
.dnew-progress-count { white-space: nowrap; font-weight: 500; color: var(--charcoal); font-size: 14px; }
.dnew-onboard-dismiss {
  position: absolute; top: 14px; right: 14px;
  width: 28px; height: 28px; border: none; background: transparent;
  color: var(--fg-3); cursor: pointer; border-radius: var(--radius-pill);
  display: flex; align-items: center; justify-content: center;
}
.dnew-onboard-dismiss svg { width: 16px; height: 16px; }
@media (hover: hover) and (pointer: fine) {
  .dnew-onboard-dismiss:hover { background: var(--paper); color: var(--charcoal); }
}

.dnew-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 16px; }
.dnew-step {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-md); padding: 11px 14px;
  color: var(--charcoal); text-decoration: none;
  font-family: var(--font-body);
  transition: border-color var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  a.dnew-step:hover { border-color: var(--sage-light); background: var(--paper); }
}
.dnew-step-mark {
  flex: none; width: 30px; height: 30px; border-radius: var(--radius-pill);
  background: var(--sage-wash); color: var(--sage-dark);
  display: flex; align-items: center; justify-content: center;
}
.dnew-step-mark svg { width: 16px; height: 16px; }
.dnew-step.is-done .dnew-step-mark { background: var(--sage); color: var(--soft-bg); }
.dnew-step-label { flex: 1; font-size: 14px; font-weight: 500; color: var(--charcoal); line-height: 1.2; }
.dnew-step-cta { font-size: 12.5px; color: var(--sage-dark); font-weight: 500; white-space: nowrap; }

/* ============================================================
   Hero
   ============================================================ */
.dnew-hero-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; margin-bottom: 18px;
}
.dnew-hello { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }
.dnew-hello img {
  width: 38px; height: 38px; border-radius: var(--radius-pill);
  object-fit: cover; box-shadow: var(--shadow-sm);
}
/* Monogram fallback when the couple haven't uploaded a profile photo. */
.dnew-hello-mono {
  flex: none; width: 38px; height: 38px; border-radius: var(--radius-pill);
  background: var(--sage); color: var(--soft-bg);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 15px; font-weight: 600;
  letter-spacing: 0.5px; box-shadow: var(--shadow-sm);
}
.dnew-title { font-size: 34px; line-height: 1.1; }
.dnew-title em { font-style: italic; color: var(--sage-dark); }
.dnew-hero-actions { display: flex; gap: 12px; flex: none; }

/* Hero grid: a big photo, a pair of stacked photos, and the "wedding at a glance"
   card (location reveal + date). Big spans both rows on the left, the two stack
   tiles fill the middle column, the glance card spans both rows on the right. */
.dnew-hero-grid {
  display: grid;
  grid-template-columns: 1.55fr 0.92fr 1.2fr;
  grid-template-rows: 152px 152px; gap: 12px; min-width: 0;
}
.dnew-tile { display: block; text-decoration: none; color: inherit; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); position: relative; }
.dnew-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (hover: hover) and (pointer: fine) {
  a.dnew-tile { transition: box-shadow var(--dur-base) var(--ease-out); }
  a.dnew-tile:hover { box-shadow: var(--shadow-md); }
}
.dnew-tile--big { grid-column: 1; grid-row: 1 / 3; }
.dnew-tile--stack { grid-column: 2; }   /* the two auto-flow into rows 1 and 2 */
/* No location panel (too few geotagged photos): the photos expand to fill the whole hero -
   the big tile on the left, a 2x2 of stills filling the right. */
.dnew-hero-grid--nopanel { grid-template-columns: repeat(4, 1fr); }
.dnew-hero-grid--nopanel .dnew-tile--big { grid-column: 1 / 3; grid-row: 1 / 3; }
.dnew-hero-grid--nopanel .dnew-tile--stack,
.dnew-hero-grid--nopanel .dnew-tile--fill { grid-column: auto; }   /* auto-flow into columns 3-4 */
.dnew-tile-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(44,44,44,0.5), transparent 60%);
  display: flex; align-items: flex-end; justify-content: center; padding: 12px;
}
.dnew-tile-overlay span { color: var(--soft-bg); font-size: 13px; font-weight: 500; letter-spacing: 0.02em; }

/* "Your wedding at a glance" card: a full-card video background with a 30% white veil
   over everything EXCEPT a clear "map window". Flex column lays out header, the window,
   and the date; the video sits behind, the veil between, the text/pin in front. */
.dnew-glance {
  grid-column: 3; grid-row: 1 / 3;
  position: relative; overflow: hidden;   /* clip the video + the veil box-shadow */
  display: flex; flex-direction: column; gap: 11px;
  background: var(--off-white); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 14px;
}
.dnew-glance-head, .dnew-glance-foot { position: relative; z-index: 2; }  /* above the veil */
.dnew-glance-head { display: flex; align-items: center; gap: 8px; }
.dnew-glance-head svg { width: 17px; height: 17px; color: var(--sage-dark); flex: none; }
.dnew-glance-head span { font-size: 14px; font-weight: 600; color: var(--charcoal); }
/* Footer row: date bottom-left, town bottom-right (desktop). */
.dnew-glance-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.dnew-glance-loc { display: flex; align-items: flex-start; gap: 6px; margin-left: auto; min-width: 0; }
.dnew-glance-loc svg { width: 13px; height: 13px; color: var(--sage-dark); flex: none; margin-top: 2px; }
.dnew-glance-loc span { font-size: 12.5px; font-weight: 500; color: var(--sage-dark); line-height: 1.3; text-align: right; }
/* Clear window: punches a hole in the 30% white veil. The huge box-shadow paints the
   veil over the whole card EXCEPT this element; the card's overflow:hidden clips it to
   the rounded card. The element itself is transparent, so the background video shows
   through crisp here. */
.dnew-glance-map {
  position: relative; z-index: 1; flex: 1 1 auto; min-height: 0;
  border-radius: var(--radius-md);
  /* crisp white frame separating the clear window from the veil (reads against the
     vivid map; blends softly into the light veil on the outer side). */
  border: 1px solid rgba(255, 255, 255, 0.92);
  box-shadow: 0 0 0 100vmax rgba(255, 255, 255, 0.85);
}
.dnew-glance-date { display: flex; align-items: center; gap: 11px; }
.dnew-glance-date svg { width: 19px; height: 19px; color: var(--sage-dark); flex: none; }
.dnew-glance-date .eyebrow { color: var(--sage-dark); }
.dnew-glance-date-main { font-family: var(--font-body); font-size: 15px; font-weight: 600; color: var(--charcoal); line-height: 1.2; margin-top: 3px; }
/* The pin marks the venue, which is dead-centre of the full-card video. Anchored to the
   card centre (not the window) so it sits exactly on the venue; the window contains the
   card centre, so it shows over the clear area. */
.dnew-glance > .dnew-globe-pin { z-index: 3; }
/* Desktop: the clear window sits above the card centre, so nudge the video up 9px
   (an 18px-taller element shifted up) to centre the globe in the window at the start, and
   move the pin up to match so it still lands on the venue. */
@media (min-width: 981px) {
  .dnew-glance > .dnew-globe { top: -18px; bottom: auto; height: calc(100% + 18px); }
  .dnew-glance > .dnew-globe-pin { top: calc(50% - 9px); }
}
/* Globe-to-venue drone reveal video, filling the WHOLE card behind the veil. Plays once
   and holds on the final venue frame (no loop - it would snap space->ground). */
.dnew-globe { display: block; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: var(--off-white); z-index: 0; }
/* Venue pin overlay. Outer element anchors the pin TIP at the panel centre (the
   venue, which lookAt keeps centred); inner element runs the drop-in animation so
   its transform doesn't fight the centring transform. Hidden until JS adds
   .is-dropped when the camera settles. */
.dnew-globe-pin { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%); pointer-events: none; z-index: 2; }
/* transform-origin at the tip (bottom): the pin plants there and the ball wobbles
   around it like a springy stick. Hidden until JS adds .is-dropped at the settle. */
.dnew-globe-pin-drop { display: block; opacity: 0; transform-origin: 50% 100%; }
.dnew-globe-pin.is-dropped .dnew-globe-pin-drop {
  animation: dnewPinDrop 1200ms both;
}
/* Drop in, then a damped left-right wobble that springs to rest (rotates about the
   planted tip). Per-keyframe timing: accelerate on the way down, ease the swings. */
@keyframes dnewPinDrop {
  0%   { opacity: 0; transform: translateY(-26px) rotate(0deg); animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.4); }
  18%  { opacity: 1; transform: translateY(0) rotate(0deg);     animation-timing-function: ease-out; }
  30%  { opacity: 1; transform: translateY(0) rotate(9deg); }
  42%  { opacity: 1; transform: translateY(0) rotate(-6.5deg); }
  54%  { opacity: 1; transform: translateY(0) rotate(4deg); }
  66%  { opacity: 1; transform: translateY(0) rotate(-2.3deg); }
  78%  { opacity: 1; transform: translateY(0) rotate(1.3deg); }
  90%  { opacity: 1; transform: translateY(0) rotate(-0.6deg); }
  /* opacity:1 on the final keyframe too, so animation-fill-mode:both holds it
     visible (without it, the forwards fill reverts to the base opacity:0 = fade out). */
  100% { opacity: 1; transform: translateY(0) rotate(0deg); }
}
.dnew-pin-shadow { fill: rgba(44, 44, 44, 0.30); }
.dnew-globe-pin svg { display: block; width: 26px; height: 36px; filter: drop-shadow(0 2px 3px rgba(44, 44, 44, 0.35)); }
/* The pin boing plays for everyone, including reduced-motion: the globe descent is
   far bigger motion and the pin is a small one-shot flourish, so it isn't worth
   suppressing. (No prefers-reduced-motion override - intentional.) */

.dnew-stats {
  display: flex; flex-wrap: wrap; margin-top: 12px;
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden;
}
.dnew-stat {
  flex: 1; min-width: 130px; padding: 14px 24px; text-align: center;
  border-right: 1px solid var(--hairline-soft);
}
.dnew-stat:last-child { border-right: none; }
.dnew-stat-num { font-family: var(--font-display); font-size: 28px; color: var(--charcoal); line-height: 1; }
.dnew-stat .eyebrow { margin-top: 6px; }

/* ============================================================
   Feature cards (browse / people)
   ============================================================ */
.dnew-feature-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px;
  gap: 28px; margin-top: 24px;
}
.dnew-feature-card {
  display: block; background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden;
  text-decoration: none; color: inherit;
}
.dnew-feature-imgs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; }
/* Sparse gallery, 1 real photo: a lone image cover-cropped across the full
   card is a ~6:1 band (brutal on portraits), so instead the whole photo is
   contained and centred over a blurred copy of itself as the backdrop. */
.dnew-feature-imgs--1up { grid-template-columns: 1fr; position: relative; overflow: hidden; }
.dnew-feature-imgs--2up { grid-template-columns: repeat(2, 1fr); }
.dnew-feature-imgs img { width: 100%; height: 128px; object-fit: cover; display: block; }
.dnew-feature-imgs .dnew-feature-img-blur {
  position: absolute; inset: 0; height: 100%;
  filter: blur(16px) saturate(0.9); transform: scale(1.15); /* scale hides the blur's soft edges */
  opacity: 0.75;
}
.dnew-feature-imgs .dnew-feature-img-contain {
  position: relative; object-fit: contain;
}
.dnew-people-strip { height: 128px; background: var(--sage-mist); position: relative; padding: 0; overflow: hidden; }
/* Avatars are absolutely placed (left set inline per index) as a left-aligned
   overlapping stack - a fixed step so any count reads as one neat cluster. */
.dnew-ppl-avatar {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 50px; height: 50px; border-radius: var(--radius-pill);
  object-fit: cover; border: 3px solid var(--soft-bg); box-shadow: var(--shadow-sm);
}
.dnew-avatar-more {
  background: var(--sage); color: var(--soft-bg);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 500;
}
/* Locked (Basic plan) people teaser - clustered/overlapping ghosts on the left,
   with the "Premium only" pill over to the right. */
.dnew-people-strip.is-locked { display: flex; align-items: center; justify-content: flex-start; padding: 0 16px; }
.dnew-avatar-ghost {
  flex: none; width: 48px; height: 48px; border-radius: var(--radius-pill);
  border: 3px solid var(--soft-bg); box-shadow: var(--shadow-sm);
  background: linear-gradient(135deg, #C7D3C0, #A8B9A0);
}
.dnew-people-strip.is-locked > .dnew-avatar-ghost + .dnew-avatar-ghost { margin-left: -22px; }
.dnew-people-lock {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end;
  padding-right: 24px; margin-left: 0;
  /* Above every avatar. The avatars carry an inline z-index (1..7, and 99 on the
     "+N" bubble) so being later in the DOM is not enough - an explicit z-index
     beats this element's auto, and the last face would sit over the pill. */
  z-index: 100;
}
.dnew-people-lock > span {
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(254, 253, 251, 0.92); color: var(--sage-dark);
  border: 1px solid var(--sage-light); border-radius: var(--radius-pill);
  padding: 7px 14px; font-size: 13px; font-weight: 500;
  box-shadow: var(--shadow-sm);
}
.dnew-people-lock svg { width: 15px; height: 15px; }
.dnew-premium-badge {
  display: inline-block; vertical-align: middle; margin-left: 8px;
  font-family: var(--font-body); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--sage-dark);
  background: var(--sage-wash); border: 1px solid var(--sage-light);
  border-radius: var(--radius-pill); padding: 3px 9px;
}
.dnew-feature-body {
  padding: 22px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.dnew-feature-title { font-family: var(--font-display); font-size: 21px; color: var(--charcoal); }
.dnew-arrow {
  flex: none; width: 40px; height: 40px; border-radius: var(--radius-pill);
  background: var(--sage-wash); color: var(--sage-dark);
  display: flex; align-items: center; justify-content: center;
}
.dnew-arrow svg { width: 18px; height: 18px; }

/* ============================================================
   Main + tools rail
   ============================================================ */
.dnew-main-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px;
  gap: 28px; align-items: start; margin-top: 24px;
}
.dnew-col { display: flex; flex-direction: column; gap: 28px; min-width: 0; }

.dnew-card {
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-sm); padding: 28px 30px;
}

/* Gather */
.dnew-gather-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 20px; }
.dnew-gather-card {
  display: block; background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden;
  text-decoration: none; color: inherit; cursor: pointer;
}
.dnew-gather-img { height: 158px; overflow: hidden; }
.dnew-gather-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dnew-gather-card-body { padding: 16px 18px; }
.dnew-gather-card-title { font-size: 15.5px; font-weight: 500; color: var(--charcoal); }

.dnew-upload-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.dnew-link-field {
  flex: 1; min-width: 240px; display: flex; align-items: center; gap: 10px;
  background: var(--off-white); border: 1px solid var(--border);
  border-radius: var(--radius-pill); padding: 11px 18px;
}
.dnew-link-field svg { flex: none; width: 18px; height: 18px; }
.dnew-link-text {
  flex: 1; min-width: 0; font-size: 15px; color: var(--charcoal);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dnew-copy-btn { min-width: 142px; }

/* Keepsakes band */
.dnew-keepsakes {
  background: var(--sage-mist); border: 1px solid var(--sage-light);
  border-radius: var(--radius-xl); padding: 36px;
}
.dnew-keepsakes-head { display: flex; flex-wrap: wrap; gap: 32px; align-items: center; }
.dnew-keepsakes-head .dnew-keepsakes-media {
  flex: 1 1 240px; max-width: 300px; aspect-ratio: 16/12;
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  overflow: hidden;          /* clip the zoom below */
}
/* The reveal video is rendered at the final framing AND size (1200x900, 4:3 -
   the approved "1.3 zoom, panned left" crop baked into the render), so it fills
   the panel 1:1 with no CSS crop or browser downscaling of an oversized clip.
   The static fallback image just covers the box. */
.dnew-keepsakes-head .dnew-keepsakes-media > video,
.dnew-keepsakes-head .dnew-keepsakes-media > img {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.dnew-keepsakes-intro { flex: 1 1 300px; }
.dnew-keepsakes-lead { font-size: 24px; font-family: var(--font-display); color: var(--charcoal); margin-top: 12px; line-height: 1.25; max-width: 22ch; }
.dnew-keepsake-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-top: 24px; }
.dnew-keepsake-card {
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 22px 22px 20px; display: flex; flex-direction: column;
}
.dnew-keepsake-card-title { font-size: 17px; font-weight: 500; color: var(--charcoal); }
.dnew-keepsake-card .caption { margin-top: 12px; flex: 1; }
.dnew-keepsake-card .btn { align-self: flex-start; font-size: 14px; padding: 11px 22px; margin-top: 16px; }

/* Storage */
.dnew-storage {
  background: #F6F1E6; border: 1px solid #E9DEC8; border-radius: var(--radius-xl);
  padding: 32px 34px; display: flex; align-items: center; gap: 24px;
  box-shadow: var(--shadow-sm); flex-wrap: wrap;
}
.dnew-storage-icon {
  flex: none; width: 64px; height: 64px; border-radius: var(--radius-pill);
  background: #E7D7B0; color: #9A8048; display: flex; align-items: center; justify-content: center;
}
.dnew-storage-icon svg { width: 30px; height: 30px; }
.dnew-storage-body { flex: 1; }
.dnew-plan-badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: #EADCBC; color: #8A7038; border-radius: var(--radius-pill);
  padding: 5px 13px; font-size: 12px; font-weight: 500; letter-spacing: 0.04em; margin-bottom: 12px;
}
.dnew-plan-badge svg { width: 13px; height: 13px; }
.dnew-storage-headline { font-family: var(--font-display); font-size: 25px; color: var(--charcoal); line-height: 1.25; }
.dnew-storage-sub { font-size: 15px; color: rgba(44,44,44,0.68); margin-top: 7px; max-width: 60ch; }
.dnew-storage-cta {
  flex: none; font-family: var(--font-body); font-size: 14px; color: var(--charcoal);
  background: transparent; border: 1px solid #D8C9A6; border-radius: var(--radius-pill);
  padding: 11px 22px; cursor: pointer; white-space: nowrap; text-decoration: none;
}

/* Recent activity */
.dnew-activity-head { display: flex; align-items: baseline; gap: 14px; margin-bottom: 20px; }
.dnew-activity-list { display: flex; flex-direction: column; gap: 12px; }
.dnew-activity-item {
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 16px 20px; display: flex; align-items: center; gap: 16px;
  text-decoration: none; color: inherit;
}
@media (hover: hover) and (pointer: fine) {
  a.dnew-activity-item { transition: box-shadow var(--dur-base) var(--ease-out); }
  a.dnew-activity-item:hover { box-shadow: var(--shadow-md); }
}
.dnew-activity-text { flex: 1; }
.dnew-activity-text .name { font-weight: 500; color: var(--charcoal); }
.dnew-activity-text .meta { color: var(--fg-2); }
.dnew-activity-thumbs { display: flex; gap: 6px; }
.dnew-activity-thumbs img { width: 46px; height: 46px; border-radius: 8px; object-fit: cover; }

/* Tools rail */
.dnew-rail { position: sticky; top: 88px; min-width: 0; }
.dnew-tools {
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 20px 18px;
}
.dnew-tools h3 { font-size: 20px; margin: 0 4px 2px; }
.dnew-tools-sub { margin: 0 4px 16px; }
.dnew-tools .eyebrow { font-size: 10.5px; margin: 0 4px 6px; display: block; }
.dnew-tool {
  display: flex; align-items: center; gap: 12px; padding: 12px;
  margin-bottom: 8px; border-radius: var(--radius-md);
  border: 1px solid var(--border-soft); background: var(--off-white);
  color: var(--charcoal); text-decoration: none;
  transition: background var(--dur-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .dnew-tool:hover, .dnew-tool-account:hover { background: var(--sage-mist); }
}
.dnew-tool-icon {
  flex: none; width: 34px; height: 34px; border-radius: var(--radius-pill);
  background: var(--sage-wash); color: var(--sage-dark);
  display: flex; align-items: center; justify-content: center;
}
.dnew-tool-icon svg { width: 18px; height: 18px; }
.dnew-tool-body { flex: 1; }
.dnew-tool-title { font-size: 14.5px; font-weight: 500; color: var(--charcoal); }
.dnew-tool-chevron { flex: none; width: 15px; height: 15px; color: var(--fg-3); }
/* Locked tool (e.g. Photobooks before the wedding) - greyed, non-interactive. */
.dnew-tool--locked { cursor: default; opacity: 0.6; }
.dnew-tool--locked .dnew-tool-icon { background: var(--hairline); color: var(--fg-3); }
.dnew-tool--locked .dnew-tool-title { color: var(--fg-2); }
.dnew-divider { height: 1px; background: var(--hairline-soft); margin: 13px 4px; }
.dnew-tool-account {
  display: flex; align-items: center; gap: 11px; padding: 9px 10px;
  border-radius: var(--radius-md); color: var(--charcoal); text-decoration: none;
  transition: background var(--dur-base) var(--ease-out);
}
.dnew-tool-account-icon { flex: none; color: var(--sage-dark); display: flex; }
.dnew-tool-account-icon svg { width: 19px; height: 19px; }
.dnew-tool-account-label { flex: 1; font-size: 14.5px; font-weight: 500; }
.dnew-tools-help { margin: 16px 4px 2px; padding-top: 14px; border-top: 1px solid var(--hairline-soft); }
.dnew-tools-help .caption { line-height: 1.5; text-align: center; }
.dnew-tools-help a { color: var(--sage-dark); }
.dnew-tool-count {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  border-radius: var(--radius-pill); font-size: 11px; font-weight: 600;
  background: var(--sage-wash); color: var(--sage-dark);
}
/* Locked CTA (e.g. photobooks before the wedding) - greyed, non-interactive. */
.dnew-btn-locked {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: var(--hairline); color: var(--fg-3);
  cursor: default; pointer-events: none; box-shadow: none; border-color: transparent;
}
.dnew-btn-locked svg { width: 15px; height: 15px; flex: none; }
/* Keepsake books are Premium only - Basic users get a clickable upsell (not a
   dead locked pill) so they have a route to upgrade. */
.dnew-btn-upsell {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: transparent; color: var(--sage-dark);
  border: 1px solid var(--sage); box-shadow: none;
}
.dnew-btn-upsell svg { width: 15px; height: 15px; flex: none; }
@media (hover: hover) and (pointer: fine) {
  .dnew-btn-upsell:hover { background: var(--sage-mist); border-color: var(--sage-dark); }
}

/* Inline text link (e.g. the onboarding "remove them now" demo-photo action). */
.dnew-inline-link {
  color: var(--sage-dark); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}

/* ---- Notices: flash confirmations + storage-expiry warnings ---------------- */
.dnew-notice {
  display: flex; align-items: center; gap: 13px;
  padding: 14px 16px; margin-bottom: 18px;
  border-radius: var(--radius-lg); border: 1px solid var(--border-soft);
  background: var(--soft-bg); box-shadow: var(--shadow-sm);
  font-size: 14px; line-height: 1.5; color: var(--charcoal);
}
.dnew-notice-icon { flex: none; display: grid; place-items: center; }
.dnew-notice-icon svg { width: 21px; height: 21px; }
.dnew-notice-body { flex: 1 1 0; min-width: 0; }
.dnew-notice-body strong { font-weight: 600; }
.dnew-notice-cta {
  flex: none; white-space: nowrap; text-decoration: none;
  padding: 8px 15px; border-radius: var(--radius-pill);
  font-size: 13px; font-weight: 600; color: #fff;
}
/* Confirmation = sage; warning = warm amber; alert (expired) = muted terracotta.
   All kept soft to suit the stationery aesthetic. */
.dnew-notice--success { background: var(--sage-wash); border-color: var(--sage-light); }
.dnew-notice--success .dnew-notice-icon { color: var(--sage-dark); }
.dnew-notice--success .dnew-notice-cta { background: var(--sage); }
.dnew-notice--warn { background: #FAF3E6; border-color: #E7D6AE; }
.dnew-notice--warn .dnew-notice-icon { color: #9C6F19; }
.dnew-notice--warn .dnew-notice-cta { background: #9C6F19; }
.dnew-notice--alert { background: #F8ECEA; border-color: #E4C7C1; }
.dnew-notice--alert .dnew-notice-icon { color: #B5503C; }
.dnew-notice--alert .dnew-notice-cta { background: #B5503C; }
/* Keep the CTA text white on hover (the global a:hover turns links sage green,
   which reads terribly on the coloured buttons) - just deepen the background. */
@media (hover: hover) and (pointer: fine) {
  .dnew-notice-cta:hover { color: #fff; }
  .dnew-notice--success .dnew-notice-cta:hover { background: var(--sage-dark); }
  .dnew-notice--warn .dnew-notice-cta:hover { background: #7F5A14; }
  .dnew-notice--alert .dnew-notice-cta:hover { background: #9C4433; }
}

/* ---- Hero meta chips: countdown + "new since last visit" ------------------- */
.dnew-hero-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 13px; }
.dnew-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: var(--radius-pill);
  font-size: 12.5px; font-weight: 500; color: var(--sage-dark);
  background: var(--sage-wash); border: 1px solid var(--sage-light);
}
.dnew-chip svg { width: 14px; height: 14px; flex: none; }
.dnew-chip strong { font-weight: 700; }
.dnew-chip--accent { background: var(--sage); border-color: var(--sage); color: #fff; }
.dnew-chip--new { background: var(--soft-bg); border-color: var(--border-soft); color: var(--charcoal-soft); }
.dnew-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sage); flex: none; }

/* ---- Waiting-for-uploads placeholder (wedding day onwards, still no photos) ---- */
.dnew-waiting {
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  min-height: 280px; padding: 40px 32px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 14px;
}
.dnew-waiting-icon {
  width: 56px; height: 56px; border-radius: var(--radius-pill);
  background: var(--sage-wash); color: var(--sage-dark);
  display: grid; place-items: center;
}
.dnew-waiting-icon svg { width: 28px; height: 28px; }
.dnew-waiting .dnew-waiting-title { font-family: var(--font-display); font-size: 26px; line-height: 1.15; color: var(--charcoal); }
.dnew-waiting .dnew-waiting-copy { font-size: 15px; line-height: 1.55; color: var(--fg-2); max-width: 46ch; }
.dnew-waiting .btn { margin-top: 4px; }

/* ---- Printed-QR-card upsell (replaces the hero collage pre-wedding, no photos) ---- */
.dnew-qrpromo {
  display: grid; grid-template-columns: minmax(0, 42%) 1fr; align-items: stretch;
  overflow: hidden; text-decoration: none; color: inherit;
  background: var(--soft-bg); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.dnew-qrpromo-media { position: relative; min-height: 280px; }
.dnew-qrpromo-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dnew-qrpromo-body { padding: 30px 34px; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 11px; }
.dnew-qrpromo .dnew-qrpromo-badge {
  font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--sage-dark); background: var(--sage-wash); border: 1px solid var(--sage-light);
  border-radius: var(--radius-pill); padding: 5px 12px;
}
.dnew-qrpromo .dnew-qrpromo-title { font-family: var(--font-display); font-size: 30px; line-height: 1.1; color: var(--charcoal); }
.dnew-qrpromo .dnew-qrpromo-lead { font-size: 15px; font-weight: 500; color: var(--sage-dark); line-height: 1.45; }
.dnew-qrpromo .dnew-qrpromo-copy { font-size: 14.5px; line-height: 1.55; color: var(--fg-2); max-width: 48ch; }
.dnew-qrpromo .dnew-qrpromo-cta {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 8px;
  font-size: 14px; font-weight: 600; color: #fff;
  background: var(--sage); border-radius: var(--radius-pill); padding: 11px 20px;
}
.dnew-qrpromo .dnew-qrpromo-cta svg { width: 16px; height: 16px; }
@media (hover: hover) and (pointer: fine) {
  .dnew-qrpromo { transition: box-shadow var(--dur-base) var(--ease-out); }
  .dnew-qrpromo:hover { box-shadow: var(--shadow-md); }
  .dnew-qrpromo:hover .dnew-qrpromo-cta { background: var(--sage-dark); }
}

/* ============================================================
   Responsive  (mobile collapse, mirrors the mobile mockup)
   ============================================================ */
@media (max-width: 980px) {
  .dnew .dnew-wrap { padding: 22px 18px 80px; }
  .dnew-feature-grid { grid-template-columns: 1fr; gap: 16px; }
  /* Flatten the two columns into one stack and interleave the sections so
     Tools sits directly above Photobooks (matches the mobile mockup order:
     Gather -> Tools -> Photobooks -> Storage -> Recent activity). */
  /* Grid (not flex) so the single track is minmax(0,1fr): it clamps each
     section's min-content (e.g. the nowrap upload-link URL) instead of letting
     it force the column wider than the viewport. order still applies to items. */
  .dnew-main-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .dnew-col, .dnew-rail { display: contents; }
  .dnew-rail { position: static; }
  .dnew-card { order: 1; }       /* Gather */
  .dnew-tools { order: 2; }      /* Tools */
  .dnew-keepsakes { order: 3; }  /* Photobooks */
  .dnew-storage { order: 4; }
  .dnew-activity { order: 5; }   /* Recent activity */
  /* flex items must be allowed to shrink below their content's intrinsic width */
  .dnew-card, .dnew-tools, .dnew-keepsakes, .dnew-storage, .dnew-activity { min-width: 0; }
  /* Hero reflows: big photo + a stacked pair (2 columns), and the glance card drops
     to a full-width row below. Fixed photo rows (img tiles have no intrinsic height,
     so an auto row would collapse them to 0). */
  .dnew-hero-grid {
    grid-template-columns: 1.25fr 1fr;
    grid-template-rows: 99px 99px auto;   /* photo rows trimmed ~20% (124 -> 99) */
  }
  .dnew-tile--big { grid-column: 1; grid-row: 1 / 3; }
  .dnew-tile--stack { grid-column: 2; }
  .dnew-glance { grid-column: 1 / 3; grid-row: 3; }
  /* No fixed card height to flex against now, so the map gets an explicit ratio.
     Flatter strip (wide + short) to match the mockup. */
  .dnew-glance-map { flex: none; aspect-ratio: 12 / 5; }

  /* No location panel on mobile: big photo (col 1, both top rows) + the stacked pair
     (col 2), with the two remaining stills filling a third row. */
  .dnew-hero-grid--nopanel {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 99px 99px 99px;
  }
  .dnew-hero-grid--nopanel .dnew-tile--big { grid-column: 1; grid-row: 1 / 3; }
  .dnew-hero-grid--nopanel .dnew-tile--stack,
  .dnew-hero-grid--nopanel .dnew-tile--fill { grid-column: auto; }
}

@media (max-width: 720px) {
  .dnew-title { font-size: 25px; }
  .dnew-hero-head { display: block; }
  /* Keep the two hero buttons on a single line (they share the width). */
  .dnew-hero-actions { display: flex; flex-direction: row; gap: 8px; margin-top: 14px; }
  .dnew-hero-actions .btn { flex: 1; min-width: 0; gap: 6px; padding: 11px 10px; font-size: 13.5px; white-space: nowrap; }
  .dnew-hero-actions .btn svg { width: 15px; height: 15px; flex: none; }
  .dnew-onboard-head { flex-direction: column; align-items: stretch; gap: 14px; padding-right: 0; }
  .dnew-onboard-headleft { padding-right: 30px; }   /* only the title needs to clear the corner X */
  /* QR-card upsell: stack image over content on mobile. */
  .dnew-qrpromo { grid-template-columns: 1fr; }
  .dnew-qrpromo-media { min-height: 170px; }
  .dnew-qrpromo-body { padding: 22px 20px; }
  .dnew-qrpromo .dnew-qrpromo-title { font-size: 25px; }
  /* Full-width progress bar with the count flush to the right (aligned with the cards). */
  .dnew-onboard-progress { width: 100%; }
  .dnew-progress-track { flex: 1; width: auto; }
  .dnew-steps { grid-template-columns: 1fr; }
  /* Notice: let the CTA drop to its own full-width line on narrow screens. */
  .dnew-notice { flex-wrap: wrap; }
  .dnew-notice-cta { width: 100%; text-align: center; }
  /* Stats stay on a single line of four (don't wrap to 2x2). */
  .dnew-stats { flex-wrap: nowrap; }
  .dnew-stat { min-width: 0; padding: 13px 6px; }
  .dnew-stat-num { font-size: 22px; }
  .dnew-stat .eyebrow { font-size: 9.5px; letter-spacing: 0.04em; }
  /* Break after the first word so every label is consistently two lines. */
  .dnew-stat .eyebrow span:first-child { display: block; }
  /* The people avatars are ~50px tall; the 128px strip (sized to match the photo
     card) leaves a lot of dead space above/below them on mobile. Tighten it so the
     row sits snugly. */
  .dnew-people-strip { height: 84px; }
  .dnew-card { padding: 22px 20px; }
  .dnew-gather-cards { grid-template-columns: 1fr; }
  .dnew-keepsakes { padding: 22px 20px; }
  .dnew-keepsakes-head { gap: 18px; }
  .dnew-keepsakes-head .dnew-keepsakes-media { max-width: none; width: 100%; }
  /* stack the upload link + copy button so the 240px field floor can't
     force a horizontal scrollbar on narrow screens */
  .dnew-upload-row { flex-direction: column; }
  .dnew-link-field { min-width: 0; width: 100%; }
  .dnew-copy-btn { width: 100%; }
  .dnew-storage { padding: 24px 22px; }
  .dnew-storage-cta { width: 100%; text-align: center; }
}
