/* Hand-edit design tweaks here. Loaded after app.css, so these rules win. No build step needed. */

/* ---------- Story timeline (chapters + milestones) ----------
   Grid based: column 1 holds the icon dot, column 2 the card. The connecting line is drawn per item so it is
   always continuous and never depends on absolute offsets. Colours come from CSS variables set on the <ol>. */
.ws-tl{position:relative;display:grid;gap:1.5rem;margin:2.5rem 0 0;padding:0;list-style:none}
.ws-tl-item{position:relative;display:grid;grid-template-columns:2.75rem minmax(0,1fr);column-gap:.875rem;align-items:start}
.ws-tl-item::before{content:"";position:absolute;left:1.375rem;top:0;bottom:-1.5rem;width:2px;margin-left:-1px;background:var(--tl-line,currentColor);opacity:.75}
.ws-tl-item:first-child::before{top:1.375rem}
.ws-tl-item:last-child::before{bottom:auto;height:1.375rem}
.ws-tl-item:only-child::before{display:none}
.ws-tl-dot{position:relative;z-index:1;display:flex;width:2.75rem;height:2.75rem;align-items:center;justify-content:center;border-radius:9999px;background:var(--tl-dot,#7B1E2E);color:var(--tl-dot-ink,#fff);box-shadow:0 0 0 5px var(--tl-bg,transparent)}
.ws-tl-card{background:rgba(255,255,255,.72);border-radius:1rem;padding:1.25rem 1.4rem}
.ws-tl-date{font-size:.875rem;font-weight:500;opacity:.8}
@media (min-width:768px){.ws-tl-item{grid-template-columns:3.25rem minmax(0,1fr);column-gap:1.25rem}.ws-tl-item::before{left:1.625rem}.ws-tl-item:first-child::before{top:1.625rem}.ws-tl-item:last-child::before{height:1.625rem}.ws-tl-dot{width:3.25rem;height:3.25rem}}

/* Story pages: secondary text uses reduced opacity for hierarchy; keep it above WCAG AA contrast on soft template colours. */
#top .opacity-70{opacity:.86}
#top .opacity-75,#top .opacity-80{opacity:.9}

/* ==========================================================================
   Homepage hero graphic: a laptop preview of a wedding story with an invitation opening on a phone.
   Decorative sample (see views/public/home.php). Class prefix hx- keeps it separate from the rest of the site.
   ========================================================================== */
.hx{--hx-ivory:#FBF8F2;--hx-champagne:#F3EADB;--hx-blush:#F6E1DC;--hx-sage:#C5D1BC;--hx-gold:#B08A45;--hx-gold-soft:#E2CD9C;
  --hx-maroon:#6B1D2A;--hx-maroon-dark:#561521;--hx-ink:#2E2626;--hx-muted:#6B5F5C;--hx-line:#E8DDCB;
  position:relative;display:flex;align-items:flex-start;margin-top:1rem}
.hx-browser{position:relative;z-index:1;flex:1;min-width:0;background:#fff;border:1px solid var(--hx-line);border-radius:16px;overflow:hidden;box-shadow:0 30px 60px -32px rgba(107,29,42,.35)}
.hx-bar{display:flex;align-items:center;gap:.4rem;padding:.6rem .85rem;background:rgba(207,194,162)}
.hx-bar i{width:9px;height:9px;border-radius:50%;background:var(--hx-gold-soft)}
.hx-bar i:nth-child(2){background:var(--hx-blush)}
.hx-bar i:nth-child(3){background:var(--hx-sage)}
.hx-url{flex:1;min-width:0;margin-left:.6rem;padding:.3rem .8rem;border-radius:999px;background:#fff;font-size:.75rem;color:var(--hx-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hx-site{padding:1.25rem 1.5rem 1.5rem;background:var(--hx-ivory)}
.hx-mini{display:flex;justify-content:space-between;align-items:center}
.hx-mini b{font-family:Jost,system-ui,sans-serif;font-weight:500;color:var(--hx-maroon);font-size:1.05rem}
.hx-mini span{font-size:.78rem;color:var(--hx-muted);margin-left:.9rem}
.hx-hero{display:grid;grid-template-columns:1.15fr .85fr;gap:1.25rem;align-items:center;margin-top:1.1rem}
.hx-kicker{font-size:.82rem;color:var(--hx-muted)}
.hx-names{font-family:Jost,system-ui,sans-serif;font-size:clamp(1.9rem,3vw,2.5rem);line-height:1.05;letter-spacing:-.01em;margin:.35rem 0 .5rem;color:var(--hx-ink)}
.hx-meta{font-size:.88rem;color:var(--hx-muted);line-height:1.45}
.hx-cd{display:flex;gap:.4rem;margin-top:1rem}
.hx-cd div{min-width:3rem;text-align:center;background:#fff;border:1px solid var(--hx-line);border-radius:10px;padding:.35rem .25rem}
.hx-cd b{display:block;font-family:Jost,system-ui,sans-serif;font-weight:500;font-size:1.3rem;line-height:1.2;color:var(--hx-maroon);font-variant-numeric:tabular-nums}
.hx-cd span{font-size:.72rem;color:var(--hx-muted)}
.hx-done{margin-top:1rem;font-size:.9rem;color:var(--hx-maroon);font-weight:500}
.hx-btn{display:inline-block;margin-top:1rem;padding:.4rem 1rem;border-radius:999px;background:var(--hx-maroon);color:#fff;font-family:Jost,system-ui,sans-serif;font-size:.82rem;font-weight:500}
.hx-arch{aspect-ratio:4/5;border-radius:999px 999px 14px 14px;background:linear-gradient(165deg,var(--hx-champagne),var(--hx-blush));box-shadow:inset 0 0 0 6px rgba(255,255,255,.75);display:grid;place-items:center;overflow:hidden}
.hx-arch span{font-family:Jost,system-ui,sans-serif;font-weight:400;font-size:2.4rem;color:var(--hx-gold);letter-spacing:.02em}
.hx-arch-img{width:100%;height:100%;object-fit:cover}
.hx-events{display:flex;flex-wrap:wrap;gap:.45rem;margin-top:1.25rem;padding-top:1.1rem;border-top:1px solid var(--hx-line)}
.hx-events span{padding:.25rem .7rem;border:1px solid var(--hx-line);border-radius:8px;background:#fff;font-size:.78rem;color:var(--hx-muted)}
.hx-events b{font-weight:600;color:var(--hx-ink)}
.hx-phone{position:relative;z-index:2;flex:none;width:196px;height:400px;margin:5rem 0 0 -2.75rem;background:#fff;border:1px solid var(--hx-line);border-radius:30px;padding:8px;box-shadow:0 28px 50px -24px rgba(46,38,38,.4)}
.hx-inv{position:relative;overflow:hidden;height:100%;border-radius:23px;background:var(--hx-maroon);color:#F5E9CF;text-align:center}
.hx-frame{position:absolute;inset:9px;border:1px solid var(--hx-gold-soft);border-radius:16px;opacity:.7}
.hx-body{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;padding:1.2rem 1rem}
.hx-small{font-size:.75rem;line-height:1.35;opacity:.9}
.hx-inames{font-family:Jost,system-ui,sans-serif;font-size:1.95rem;line-height:1.1;color:var(--hx-gold-soft)}
.hx-inames i{display:block;font-style:normal;font-size:1rem;color:#F5E9CF;opacity:.8}
.hx-idate{font-family:Jost,system-ui,sans-serif;font-size:.95rem;letter-spacing:.02em}
.hx-days{font-size:.8rem;padding:.2rem .7rem;border:1px solid var(--hx-gold-soft);border-radius:999px}
.hx-days b{font-family:Jost,system-ui,sans-serif;font-weight:500;font-variant-numeric:tabular-nums}
.hx-rsvp{margin-top:.3rem;padding:.4rem 1.1rem;border-radius:999px;background:var(--hx-gold);color:#fff;font-family:Jost,system-ui,sans-serif;font-size:.8rem;font-weight:500}
/* the invitation opens once: two maroon doors slide away and the seal fades */
.hx-inv::before,.hx-inv::after{content:"";position:absolute;top:0;bottom:0;width:50.5%;background:var(--hx-maroon-dark);z-index:3;animation:hxdoors 1.1s cubic-bezier(.7,0,.2,1) 1s both}
.hx-inv::before{left:0;--dir:-101%}
.hx-inv::after{right:0;--dir:101%}
.hx-seal{position:absolute;z-index:4;left:50%;top:50%;width:56px;height:56px;margin:-28px 0 0 -28px;border-radius:50%;background:var(--hx-gold);color:#fff;display:grid;place-items:center;font-family:Jost,system-ui,sans-serif;font-weight:500;font-size:1rem;animation:hxseal .5s ease 1s both}
@keyframes hxdoors{to{transform:translateX(var(--dir))}}
@keyframes hxseal{to{opacity:0;transform:scale(.6)}}
.hx-caption{margin-top:1.5rem;font-size:.92rem;color:#6B5F5C}
@media (max-width:575.98px){
  .hx-phone{display:none}
  .hx-hero{grid-template-columns:1fr}
  .hx-hero .hx-arch{order:-1;width:55%;margin-inline:auto}
  .hx-mini span{display:none}
  .hx::before{display:none}
}
@media (prefers-reduced-motion:reduce){.hx-inv::before,.hx-inv::after,.hx-seal{display:none}}
/* Grid columns default to a minimum width based on their content ("min-width:auto"), which can force this
   column - and the whole page - wider than the viewport on mobile. min-width:0 lets it shrink to fit instead. */
.hx-col{min-width:0}

/* ==========================================================================
   Desktop top nav: a small heart pops up above each link on hover (desktop only —
   nav[aria-label="Main"] is already hidden below the 1150px breakpoint via Tailwind).
   ========================================================================== */
header nav[aria-label="Main"] a{position:relative}
header nav[aria-label="Main"] a::after{
  content:"";
  position:absolute;
  left:50%;
  top:-13px;
  width:12px;height:11px;
  transform:translateX(-50%) scale(.4);
  background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5C2,5.42,4.42,3,7.5,3c1.74,0,3.41,0.81,4.5,2.09C13.09,3.81,14.76,3,16.5,3C19.58,3,22,5.42,22,8.5c0,3.78-3.4,6.86-8.55,11.54L12,21.35z' fill='%23E4002B'/%3E%3C/svg%3E");
  opacity:0;
  transition:opacity .2s ease, transform .2s ease;
  pointer-events:none;
}
header nav[aria-label="Main"] a:hover::after{opacity:1;transform:translateX(-50%) scale(1)}
header nav[aria-label="Main"] a[aria-current="page"]::after{opacity:1;transform:translateX(-50%) scale(1)}
@media (prefers-reduced-motion:reduce){header nav[aria-label="Main"] a::after{transition:none}}


/* ==========================================================================
   Homepage hero background video (Admin -> Site -> Hero videos). Two stacked <video> elements crossfade; a tint layer
   (colour + strength from Site settings) sits on top so the footage reads as a soft, light texture.
   ========================================================================== */
.hv-bg{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none;background-size:cover;background-position:center}
.hv-v{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity 1s ease}
.hv-v.on{opacity:1}
.hv-tint{position:absolute;inset:0}
.hv-fade{position:absolute;left:0;right:0;bottom:0;height:110px}
/* text shield: an extra, softer layer of the same tint behind the headline column (fades out toward the laptop/phone graphic),
   so the words stay readable even over dark footage */
/* --hv-shield-op is set per-request from the tint-strength setting (see hero_video.php), so lowering the
   admin slider actually reveals more video everywhere, instead of this layer staying fixed. Smooth continuous
   fade (no flat block) so there is no hard "wall" between the readable text zone and the visible video. */
.hv-shield{position:absolute;inset:0;background:linear-gradient(90deg,rgba(var(--hv-rgb),var(--hv-shield-op,.7)) 0%,rgba(var(--hv-rgb),0) 82%)}
@media (max-width:1023px){.hv-shield{background:linear-gradient(180deg,rgba(var(--hv-rgb),var(--hv-shield-op,.7)) 0%,rgba(var(--hv-rgb),0) 82%)}}
.hv-off video{display:none}
/* the caption under the laptop graphic sits outside the text shield: give it its own soft backing while a video is behind it */
.has-hv .hx-caption{display:inline-block;padding:.55rem .9rem;border-radius:.75rem;background:rgba(var(--hv-rgb,251,248,242),.93);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}

/* ==========================================================================
   Login / Register right-hand panel: one real wedding photo (a different one per page --
   see AuthController), with a warm maroon tint (matches the site palette) so the quote
   text stays readable over any part of the photo.
   ========================================================================== */
.auth-photo{overflow:hidden;background:#2E2526;background-size:cover;background-position:center}
.auth-photo-tint{position:absolute;inset:0;background:linear-gradient(180deg,rgba(123,30,46,.32) 0%,rgba(46,21,29,.22) 45%,rgba(46,21,29,.28) 70%,rgba(20,9,13,.55) 100%)}
.auth-photo-content{position:absolute;left:0;right:0;bottom:0;padding:3.25rem 3rem 2.5rem;background:linear-gradient(180deg,transparent,rgba(20,9,13,.82) 40%,rgba(15,7,10,.94) 100%);text-align:center}
.auth-photo-content p{text-shadow:0 1px 12px rgba(0,0,0,.45)}
.auth-photo-content p:last-child{margin-bottom:0}
.auth-photo-sub{color:rgba(255,255,255,.9)}
@media (min-width:1280px){.auth-photo-content{padding:3.75rem 4rem 2.75rem}}

/* ==========================================================================
   Mobile story-page section nav (Invitation / Our story / Events / Gallery / ... / RSVP):
   it scrolls horizontally when there are more sections than fit on a narrow screen, but the
   native scrollbar track/thumb looked like a UI glitch (especially baked into static preview
   screenshots). Hide the scrollbar visually; the row still scrolls fine by touch/swipe/drag.
   ========================================================================== */
nav[aria-label="Story sections"]{scrollbar-width:none;-ms-overflow-style:none}
nav[aria-label="Story sections"]::-webkit-scrollbar{display:none;height:0}

/* Defensive fix for a whole class of mobile horizontal-overflow bugs across the dashboard: a CSS Grid
   item's default minimum width is based on its content ("min-content"), not 0, so a single long
   unwrapped string (a URL, a long couple's name, etc.) inside any grid cell can silently force the
   entire grid — and the whole page — wider than the viewport. This safely allows every grid item to
   shrink to fit; anything that still needs truncating/wrapping already has its own rules for that. */
.grid > * { min-width: 0; }
