*{box-sizing:border-box}
/* Sticky-footer layout: body is a full-height flex column so a short page still fills the viewport and the
   footer (margin-top:auto below) is pushed to the bottom instead of floating mid-screen; tall pages scroll
   normally with the footer flowing after the content. */
body{margin:0;font-family:var(--sans);color:rgba(var(--cream),.82);line-height:1.5;background:var(--bg-page);min-height:100svh;display:flex;flex-direction:column}
/* Full-width content region between header and footer. It is the flex child that grows (pushing the footer
   to the bottom on short pages); the page's own root does its normal `margin:0 auto` centering INSIDE this,
   unaffected by the body's flex layout. min-width:0 stops a wide child from forcing horizontal overflow. */
.app-main{flex:1 0 auto;width:100%;min-width:0}
/* Shared globe backdrop (rendered by _Layout when ViewData["GlobeBackdrop"] is set). Fixed to the
   viewport, anchored to the area UNDER the header exactly like the login canvas and sized to the login
   globe's old 115cqw — so it renders pixel-identically on login and every album/bookshelf/hub page.
   z-index:-1 layers it ABOVE the body's purple --bg-page gradient but BELOW all content (header, book
   art, login card). Resize via the 1.15 factor; move vertically via the 0.46 fraction. (--header-h is
   the single-source-of-truth header height defined further down next to .app-header.) */
.canvas-globe{
    position:fixed; left:50%;
    top:calc(var(--header-h) + 0.46 * (100svh - var(--header-h)));
    transform:translate(-50%,-50%);
    width:calc(1.15 * min(1264px, 96vw, (100svh - var(--header-h)) * 1264 / 980));
    height:auto; opacity:.4; z-index:-1; pointer-events:none; user-select:none;
}
.eyebrow{font-family:var(--sans);font-weight:400;font-size:10px;text-transform:uppercase;letter-spacing:.28em;color:rgba(var(--cream),.55)}
.display-title{font-family:var(--serif);font-weight:500;color:var(--gold);text-shadow:var(--glow-title);letter-spacing:-.02em;line-height:1}
.btn-gold{font-family:var(--sans);font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.14em;color:var(--ink-on-gold);background:var(--grad-gold-cta);border:0;border-radius:var(--r-pill);padding:12px 24px;box-shadow:var(--glow-cta);cursor:pointer;transition:filter .18s;text-decoration:none;display:inline-block}
.btn-gold:hover{filter:brightness(1.1)}
.btn-ghost{font-family:var(--sans);font-weight:500;font-size:13px;text-transform:uppercase;letter-spacing:.12em;color:rgba(var(--cream),.85);background:rgba(255,255,255,.04);border:1px solid rgba(243,201,105,.3);border-radius:var(--r-pill);padding:11px 22px;cursor:pointer;transition:background .18s;text-decoration:none;display:inline-block}
.btn-ghost:hover{background:rgba(255,255,255,.09)}
.pill{font-family:var(--sans);font-weight:500;font-size:10.5px;text-transform:uppercase;letter-spacing:.18em;color:rgba(var(--cream),.85);background:rgba(255,255,255,.04);border:1px solid rgba(243,201,105,.22);border-radius:var(--r-pill);padding:6px 12px;display:inline-block}
.badge{font-family:var(--sans);font-weight:500;font-size:8px;text-transform:uppercase;letter-spacing:.2em;color:var(--ink-on-gold);background:var(--grad-gold-cta);border-radius:var(--r-pill);padding:3px 8px;display:inline-block}
.glass-panel{background:rgba(14,10,31,.6);border:1px solid rgba(243,201,105,.25);border-radius:var(--r-card);box-shadow:var(--shadow-glass);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);padding:16px 18px}
.night-card{background:var(--bg-night-card);border:1px solid rgba(243,201,105,.18);border-radius:var(--r-card);box-shadow:inset 0 0 80px rgba(243,201,105,.04);padding:18px}
.parchment-panel{background:var(--bg-parch);border:1px solid var(--gold-bronze);border-radius:var(--r-parch);box-shadow:var(--shadow-parch);padding:20px 22px;color:var(--ink)}
.ornament{display:flex;align-items:center;justify-content:center;gap:12px}
.ornament .rule{height:1px;width:90px;background:linear-gradient(90deg,transparent,rgba(243,201,105,.85))}
.ornament .rule.r{background:linear-gradient(270deg,transparent,rgba(243,201,105,.85))}
.ornament .dot{width:6px;height:6px;border-radius:50%;background:var(--gold);box-shadow:0 0 8px rgba(243,201,105,.95)}
/* cookie consent (used by Task 3's _CookieConsent partial) */
.cookie-consent{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);z-index:60;display:flex;align-items:center;gap:16px;max-width:min(720px,calc(100vw - 32px));padding:12px 18px}
.cookie-consent__actions{display:flex;gap:10px;flex:0 0 auto}
.drawer-backdrop{position:fixed;inset:0;z-index:55;background:rgba(0,0,0,.45)}
.app-drawer{position:fixed;top:0;right:0;z-index:56;width:300px;height:100vh;padding:20px 16px;
  background:linear-gradient(180deg,#1c1230,#140c24);border-left:2px solid var(--gold);
  box-shadow:-12px 0 40px rgba(0,0,0,.5);transform:translateX(100%);transition:transform .22s ease}
.app-drawer.open{transform:translateX(0)}
.drawer-group{margin:12px 0;border-top:1px solid rgba(255,255,255,.06);padding-top:8px;display:flex;flex-direction:column}
.drawer-group:first-child{border-top:0;padding-top:0}
/* Match the legacy slide menu: bright white links, GOLD-TEXT hover (no background box), and a reset
   so the logout <button> looks identical to the <a> links instead of a default gray button box. */
.drawer-link{display:block;width:100%;padding:9px 6px;border-radius:8px;font-family:inherit;font-size:15px;font-weight:600;text-align:left;color:#fff;text-decoration:none;background:none;border:0;cursor:pointer;transition:color .15s ease}
.drawer-link:hover,.drawer-link:focus{color:#ffd54a}
/* Unseen-shared count pill next to "Your Albums" (legacy navBadgeAlbums). Gold pill, dark text, 99+ cap. */
.drawer-badge{display:inline-block;min-width:20px;margin-left:8px;padding:1px 7px;border-radius:var(--r-pill);background:var(--grad-gold-cta);color:var(--ink-on-gold);font-family:var(--sans);font-weight:700;font-size:11px;line-height:16px;text-align:center;vertical-align:middle}
.drawer-logout-form{margin:0;display:flex}
/* Drawer identity header: gold initials avatar + name/email (links to /account). The following nav-group's
   top border serves as the divider, so no border here. */
.drawer-profile{display:flex;align-items:center;gap:12px;padding:4px 6px 12px;text-decoration:none}
.drawer-avatar{flex:none;width:42px;height:42px;border-radius:999px;display:grid;place-items:center;
  background:var(--grad-gold-cta);color:var(--ink-on-gold);font-family:var(--sans);font-weight:600;font-size:15px;
  box-shadow:0 0 16px rgba(243,201,105,.35)}
.drawer-profile-meta{display:flex;flex-direction:column;min-width:0}
.drawer-profile-name{color:#fff;font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.drawer-profile-email{color:rgba(var(--cream),.55);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* SINGLE SOURCE OF TRUTH for the header's height. The header is fluid: its tallest child (the brand
   logo) is clamp(70px,9.5vh,110px) and it adds clamp(6px,.9vh,11px) padding top+bottom — so it scales
   with the viewport (≈85px on a 749px window, up to ~132px at 1080px). Every full-viewport canvas page
   (login, album, bookshelf, hub) must subtract EXACTLY this from 100svh; a fixed-px guess only matched
   at one screen height and left a gap that overflow:hidden sliced into a band. Keep this in lock-step
   with the .app-header padding + .app-brand img height below. Consumed by login.css + album.css. */
:root { --header-h: calc(clamp(70px, 9.5vh, 110px) + 2 * clamp(6px, .9vh, 11px)); }

/* Transparent 3-column header: back (left) | centered logo | globe+login+menu (right). Sizes are
   clamp()-fluid (consistent chrome on every page, gentle scaling). Real height always == var(--header-h). */
.app-header{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:clamp(6px,.9vh,11px) clamp(12px,2vw,28px);background:transparent}
.app-header-left{justify-self:start}
.app-header-right{justify-self:end;display:flex;align-items:center;gap:clamp(8px,1.2vw,16px)}
.app-brand-group{justify-self:center;display:flex;align-items:center;gap:clamp(28px,4vw,64px)}  /* back + logo + globe, hugging the centre; gap = how close they sit */
.app-brand{display:block;line-height:0}
.app-brand img{height:clamp(70px,9.5vh,110px);width:auto;display:block}
.hdr-icon{display:inline-flex;align-items:center;cursor:pointer;transition:transform .12s ease}
.hdr-icon:hover{transform:scale(1.06)}
.hdr-icon img{height:clamp(63px,8.6vh,99px);width:auto;display:block}
.app-header-right .icon-btn{width:clamp(44px,5.6vh,56px);height:clamp(44px,5.6vh,56px)}
.app-header-right .icon-btn svg{width:clamp(22px,2.9vh,30px);height:clamp(22px,2.9vh,30px)}
.app-header-right .btn-ghost{padding:clamp(12px,1.5vh,16px) clamp(20px,2.4vw,30px);font-size:clamp(13px,1.6vh,16px)}
.icon-btn{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;border:1px solid rgba(243,201,105,.28);background:rgba(255,255,255,.04);cursor:pointer}
.icon-btn svg{width:20px;height:20px}
.app-footer{margin-top:auto;display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-top:1px solid rgba(243,201,105,.12);color:rgba(var(--cream),.55);font-size:12px}
.app-footer a{color:rgba(var(--cream),.7);text-decoration:none}
.app-footer a:hover{color:var(--gold)}
.placeholder{min-height:60vh;display:grid;place-items:center;padding:48px 24px}
.placeholder__card{max-width:440px;text-align:center}
.placeholder__title{font-size:30px;margin:8px 0 12px}
.placeholder__msg{font-size:14px;color:rgba(var(--cream),.72);margin:0 0 20px}

/* Email-confirmation reminder (claim-driven; see _ConfirmEmailBanner.cshtml) — a FLOATING night-glass
   card (position:fixed, so it never pushes page layout or adds scroll the way the old full-width banner
   did). Bottom-right, dismissible for the session, styled to match the sg-dialog night surface. */
.confirm-card{position:fixed;z-index:1200;left:20px;bottom:20px;max-width:360px;width:calc(100% - 40px);
  display:flex;align-items:flex-start;gap:.75rem;padding:14px 16px;border-radius:14px;
  background:linear-gradient(160deg,rgba(30,22,64,.92),rgba(18,11,38,.96));
  border:1px solid rgba(243,201,105,.25);
  box-shadow:0 18px 50px rgba(10,7,24,.55),0 0 24px rgba(243,201,105,.06);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  color:rgb(var(--cream));opacity:1;transform:translateY(0);transition:opacity .2s ease,transform .2s ease;}
.confirm-card.is-leaving{opacity:0;transform:translateY(8px);}
.confirm-card-body{flex:1;display:flex;flex-direction:column;gap:.6rem;}
.confirm-card-text{font-size:.9rem;line-height:1.45;color:rgba(var(--cream),.9);}
.confirm-card-resend{margin:0;}
.confirm-card-resend button{background:linear-gradient(135deg,var(--gold-pale),var(--gold) 60%,var(--gold-bronze));
  color:var(--ink-on-gold);border:0;border-radius:999px;padding:.4rem 1.1rem;font-weight:600;font-size:.82rem;cursor:pointer;
  box-shadow:0 0 14px rgba(243,201,105,.35),inset 0 1px 0 rgba(255,255,255,.4);transition:filter .15s ease;}
.confirm-card-resend button:hover{filter:brightness(1.08);}
.confirm-card-resend button[disabled]{opacity:.6;cursor:default;}
.confirm-card-dismiss{flex:none;background:transparent;border:0;cursor:pointer;color:rgba(var(--cream),.55);
  padding:2px;line-height:0;transition:color .15s ease;}
.confirm-card-dismiss:hover{color:rgba(var(--cream),.9);}
.confirm-card-dismiss svg{width:16px;height:16px;}

/* Ad placeholder — HIDDEN until the real AdSense unit ships (post-approval). AdSlotViewComponent still
   renders the gated container (so the Free/anon tier gate stays provable + the markup is reserved), but the
   bare "Advertisement" label must never show to users while there is no actual ad — it was unstyled and
   leaked as plain text into pages (e.g. /photos). Remove this rule when the real <ins class="adsbygoogle">
   unit is injected in Components/AdSlot/Default.cshtml. */
.sg-adslot{display:none;}
