/* StudioCollage website. Mobile-first, one file, no framework.
   Tokens mirror the editor (~dev/app/src/style.css) so site and app feel like
   one product; the display rules (pastel bands, gradient CTA, rounded cards)
   are the site's own voice, validated on the round-2 mockup. */

/* ---------- Tokens ---------- */
:root {
  --ground: #f5f5f7;
  --surface: #ffffff;
  --ink: #1d1d1f;
  --ink-soft: #3a3a3e;
  --muted: #6e6e73;
  --line: #e5e5ea;
  --line-2: #eeeef1;
  --accent: #ff4d67;
  --accent-press: #ec3a55;
  --accent-soft: #ffe8ec;
  --amber: #ffb020;
  --teal: #22c7a0;
  --blue: #5b8cff;
  --lilac: #8b6cff;
  --coral-2: #ff7a45;
  --pink: #ff7aa8;
  --peach: #fff1e6;
  --lilac-soft: #efe9ff;
  --mint: #e3faf3;
  --sky: #e6efff;
  --rose: #ffe6ee;
  --lemon: #fff6d6;
  --r-card: 18px;
  --r-ctl: 12px;
  --r-pill: 999px;
  --sh-sm: 0 1px 2px rgba(20, 22, 40, .06), 0 1px 3px rgba(20, 22, 40, .05);
  --sh-md: 0 10px 28px rgba(24, 26, 48, .10), 0 2px 6px rgba(24, 26, 48, .06);
  --sh-lg: 0 26px 60px rgba(24, 26, 48, .18), 0 8px 18px rgba(24, 26, 48, .10);
  --sans: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --gradient-cta: linear-gradient(100deg, #ff4d67, #ff7a45 70%, #ffb020);
  --gradient-band: linear-gradient(110deg, #ff4d67, #ff7a45 55%, #ffb020);
  --gradient-hero: linear-gradient(135deg, #fff1e6 0%, #efe9ff 48%, #e3faf3 100%);
  --container: 1200px;
  --gutter: 20px;
}

@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 500 800;
  font-display: swap;
  src: url("../fonts/plus-jakarta-sans-variable.woff2") format("woff2");
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
/* The width/height attributes (set for layout stability) must not pin the
   rendered height once CSS sizes the width. */
img { height: auto; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
p { margin: 0; }
h1, h2, h3, h4, .h3 {
  margin: 0;
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.1;
  text-wrap: pretty;
}
h1 { font-size: 38px; }
h2 { font-size: 30px; }
h3, .h3 { font-size: 20px; display: block; }
.lead { font-size: 17px; line-height: 1.5; color: var(--ink-soft); }
.muted { color: var(--muted); }
.center { text-align: center; }
.ico { flex-shrink: 0; }
.ico-accent { color: var(--accent); }
.skip {
  position: absolute; left: -999px; top: 8px; z-index: 100;
  background: var(--ink); color: #fff; padding: 10px 16px; border-radius: var(--r-pill);
}
.skip:focus { left: 8px; }
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }
.container.narrow { max-width: 760px; }
.section { padding: 56px 0; }
.section-head { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
/* The head often wraps its heading and lead in a div so a link can sit beside
   them on desktop; that div needs its own rhythm, headings carry no margin. */
.section-head > div { display: flex; flex-direction: column; gap: 10px; align-items: inherit; }
.section-head.center { align-items: center; text-align: center; }
.section-head .lead { font-size: 16px; }
.link-more { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.link-more:hover { color: var(--accent); }
.btn-row { display: flex; flex-direction: column; gap: 10px; width: 100%; margin-top: 6px; }
.bg-ground { background: var(--ground); }
.bg-lilac { background: var(--lilac-soft); }
.bg-peach { background: var(--peach); }
.bg-mint { background: var(--mint); }
.bg-sky { background: var(--sky); }
.bg-rose { background: var(--rose); }
.bg-lemon { background: var(--lemon); }

/* ---------- Buttons, chips, tags ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 52px; padding: 0 24px; border: 0; border-radius: var(--r-pill);
  font: inherit; font-weight: 700; font-size: 16px; white-space: nowrap; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--gradient-cta); color: #fff; box-shadow: 0 10px 24px rgba(255, 77, 103, .28); }
.btn-primary:hover { filter: brightness(1.04); }
.btn-dark { background: var(--ink); color: #fff; }
.btn-white { background: #fff; color: var(--ink); box-shadow: var(--sh-sm); }
.btn-ghost { background: transparent; border: 2px solid var(--line); }
.btn-lg { height: 56px; font-size: 17px; }
.btn-sm { height: 44px; padding: 0 18px; font-size: 15px; }
.btn-xs { height: 36px; padding: 0 14px; font-size: 13px; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 18px;
  border: 1.5px solid var(--line); border-radius: var(--r-pill); background: #fff;
  font-weight: 700; font-size: 15px; white-space: nowrap;
}
.chip:hover { border-color: var(--ink); }
.chip.is-on { background: var(--ink); color: #fff; border-color: var(--ink); }
.chip-sm { height: 36px; padding: 0 12px; font-size: 13px; }
.chip-row { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 18px; scrollbar-width: none; }
.chip-row::-webkit-scrollbar { display: none; }
.tag {
  display: inline-flex; align-items: center; height: 28px; padding: 0 11px;
  border-radius: var(--r-pill); background: var(--ground); font-weight: 700; font-size: 12px; color: var(--ink-soft);
}
.tag.is-on { background: var(--ink); color: #fff; }
.tag-white { background: #fff; }
.tag-lilac { color: var(--lilac); }
.mt-18 { margin-top: 18px; }
.pt-0 { padding-top: 0; }
.badge {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 11px;
  border-radius: var(--r-pill); background: #fff; box-shadow: var(--sh-md); font-weight: 800; font-size: 12px;
}
.badge-accent { background: var(--accent); color: #fff; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 14px;
  border-radius: var(--r-pill); font-weight: 800; font-size: 13px; letter-spacing: .02em;
  background: var(--accent-soft); color: var(--accent);
}
.eyebrow-white { background: #fff; color: var(--lilac); box-shadow: var(--sh-sm); }
.round-ico {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 52px; height: 52px; border-radius: 50%; color: #fff;
}
/* One hue vocabulary for every coloured disc (.round-ico and .cat-ico). The
   class name is built by concatenation in the templates, so a search for
   "round-coral" finds nothing: do not delete these as dead CSS. */
.round-coral { background: var(--accent); }
.round-orange { background: var(--coral-2); }
.round-lilac { background: var(--lilac); }
.round-teal { background: var(--teal); }
.round-blue { background: var(--blue); }
.round-amber { background: var(--amber); }
.round-pink { background: var(--pink); }
.round-ink { background: var(--ink); }
.round-sky { background: var(--sky); }
.round-mint { background: var(--mint); }
.round-peach { background: var(--peach); }
.round-lemon { background: var(--lemon); }

/* Local-only editorial pipeline band on the guides hub. Striped edge and a
   muted card so it can never be mistaken for published content; it is never
   rendered in production, see pages/guides.php. */
.dev-band { border-top: 3px dashed var(--line); }
.dev-note {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 18px;
  padding: 8px 14px; border-radius: var(--r-pill);
  background: var(--lemon); color: var(--ink-soft);
  font-size: 13px; font-weight: 700;
}
.dev-note code { font: inherit; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.guide-item.is-scheduled { opacity: .82; border: 1px dashed var(--line); box-shadow: none; }
.guide-item.is-scheduled:hover { opacity: 1; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, .88); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.header-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 60px; }
.brand { display: inline-flex; align-items: center; gap: 9px; }
.brand-name { font-weight: 800; font-size: 18px; letter-spacing: -.03em; }
.header-actions { display: flex; align-items: center; gap: 4px; }
.header-actions .btn-sm { height: 40px; padding: 0 14px; font-size: 14px; }
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border: 0; background: transparent; color: var(--ink); border-radius: var(--r-ctl); cursor: pointer;
}
.nav-toggle .ico-close, .nav-open .nav-toggle .ico-open { display: none; }
.nav-open .nav-toggle .ico-close { display: block; }
.site-nav {
  display: none; position: absolute; left: 0; right: 0; top: 60px;
  flex-direction: column; padding: 12px var(--gutter) 20px; background: #fff; box-shadow: var(--sh-md);
}
.nav-open .site-nav { display: flex; }
.site-nav > a { padding: 14px 12px; font-weight: 700; font-size: 17px; border-radius: var(--r-ctl); }
.site-nav > a.is-active { background: var(--ground); }
.site-nav > a:hover { color: var(--accent); }
.lang-menu { position: relative; }
.lang-current { display: inline-flex; align-items: center; gap: 6px; padding: 14px 12px; font-weight: 700; font-size: 15px; }
.lang-list { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 12px 8px; }
.lang-list a { display: inline-flex; height: 36px; align-items: center; padding: 0 12px; border: 1.5px solid var(--line); border-radius: var(--r-pill); font-weight: 700; font-size: 14px; }

/* ---------- Hero ---------- */
.hero-band { background: var(--gradient-hero); }
/* flow-root keeps the editor mock's negative margin from collapsing through
   the hero: the hero ends 120/260px above the mock, which then overlaps the
   next section as designed. */
.hero { display: flow-root; padding: 36px 0 0; }
.hero .container.center { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.hero-title { font-size: 40px; max-width: 900px; }
.hero-lead { max-width: 640px; }
.cat-row { display: flex; gap: 18px; width: calc(100% + 2 * var(--gutter)); margin: 14px calc(-1 * var(--gutter)) 0; padding: 4px var(--gutter); overflow-x: auto; scrollbar-width: none; }
.cat-row::-webkit-scrollbar { display: none; }
.cat { display: flex; flex-direction: column; align-items: center; gap: 8px; flex-shrink: 0; font-weight: 700; font-size: 12px; }
.cat-ico { display: inline-flex; align-items: center; justify-content: center; width: 60px; height: 60px; border-radius: 50%; color: #fff; transition: transform .15s ease; }
.cat:hover .cat-ico { transform: translateY(-3px) scale(1.04); }
.editor-wrap { padding-top: 28px; margin-bottom: -120px; position: relative; z-index: 2; }
.section-templates { padding-top: 160px; }

/* ---------- Editor mock ---------- */
.editor-mock {
  background: #fff; border: 1px solid var(--line-2); border-radius: 24px; box-shadow: var(--sh-lg); overflow: hidden;
  max-width: 1160px; margin: 0 auto;
}
.em-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 50px; padding: 0 14px; border-bottom: 1px solid var(--line-2); }
.em-brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 800; font-size: 15px; letter-spacing: -.02em; }
.em-doc { display: none; }
.em-actions { display: inline-flex; gap: 8px; }
.em-actions .chip-sm { display: none; }
.em-body { display: flex; flex-direction: column; }
.em-rail { display: none; }
.em-canvas { background: var(--ground); padding: 16px; display: flex; justify-content: center; }
.em-canvas .collage { width: 100%; max-width: 520px; }
.em-panel { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.em-panel-head { display: flex; align-items: center; justify-content: space-between; }
.em-panel-title { display: inline-flex; align-items: center; gap: 8px; font-weight: 800; font-size: 14px; }
.em-proposals { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.em-proposals .proposal:nth-child(n+4) { display: none; }
.proposal { position: relative; display: block; border-radius: 14px; padding: 3px; }
.proposal.is-picked { box-shadow: 0 0 0 3px var(--accent); background: #fff; }
.proposal .badge { position: absolute; left: 10px; top: 10px; height: 24px; font-size: 11px; }

/* ---------- Collage thumbnails ---------- */
.collage {
  display: grid; gap: 4px; padding: 4px; width: 100%;
  background: #fff; border-radius: 14px; box-shadow: var(--sh-md); overflow: hidden;
}
.collage.collage-flat { box-shadow: none; border: 1px solid var(--line-2); border-radius: 12px; gap: 3px; padding: 3px; }
.collage.gap-lg { gap: 6px; padding: 6px; border-radius: 18px; }
.collage .cell { position: relative; overflow: hidden; border-radius: 7px; min-width: 0; min-height: 0; background: var(--line-2); }
/* --focus is the subject's position inside the photo, set by photo_img() from
   config/photos.php. Every crop below honours it, so a face never leaves the
   frame whatever the cell shape; 50% 50% is the fallback for a photo whose
   subject fills the image. */
.collage .cell img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: var(--focus, 50% 50%); }
.ar-1-1 { aspect-ratio: 1 / 1; }
.ar-4-5 { aspect-ratio: 4 / 5; }
.ar-9-16 { aspect-ratio: 9 / 16; }
.ar-a4 { aspect-ratio: 210 / 297; }
.ar-cover { aspect-ratio: 820 / 312; }
.ar-16-9 { aspect-ratio: 16 / 9; }
.ar-3-2 { aspect-ratio: 3 / 2; }
.ar-8-7 { aspect-ratio: 8 / 7; }
.ar-7-6 { aspect-ratio: 7 / 6; }
.ar-7-5 { aspect-ratio: 7 / 5; }
.ar-heart { aspect-ratio: 12 / 11; }
.layout-grid2x2 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.layout-cols2 { grid-template-columns: 1fr 1fr; }
.layout-cols3 { grid-template-columns: 1fr 1fr 1fr; }
.layout-cols4 { grid-template-columns: repeat(4, 1fr); }
.layout-cols5 { grid-template-columns: repeat(5, 1fr); }
.layout-rows2 { grid-template-rows: 1fr 1fr; }
.layout-bigleft { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; }
.layout-bigleft .cell:first-child { grid-row: 1 / 3; }
.layout-bigtop { grid-template-columns: repeat(3, 1fr); grid-template-rows: 1.6fr 1fr; }
.layout-bigtop .cell:first-child { grid-column: 1 / 4; }
.layout-magazine { grid-template-columns: repeat(3, 1fr); grid-template-rows: 1.4fr 1fr; }
.layout-magazine .cell:first-child { grid-column: 1 / 3; }
.layout-tall3 { grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, 1fr); }
.layout-tall3 .cell:first-child { grid-row: 1 / 4; }
.layout-mosaic { grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); }
.layout-mosaic .cell:first-child { grid-column: 1 / 3; grid-row: 1 / 3; }
.layout-mosaic .cell:nth-child(5) { grid-column: 2 / 4; }
.layout-story { grid-template-rows: 1.2fr 1fr 1fr; }
.layout-grid3x2 { grid-template-columns: repeat(3, 1fr); grid-template-rows: 1fr 1fr; }
.layout-grid4x2 { grid-template-columns: repeat(4, 1fr); grid-template-rows: 1fr 1fr; }
.layout-grid3x3 { grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); }
.layout-grid4x3 { grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 1fr); }
.layout-bigplus4 { grid-template-columns: repeat(4, 1fr); grid-template-rows: 2fr 1fr; }
.layout-bigplus4 .cell:first-child { grid-column: 1 / 5; }
.layout-heart { padding: 0; background: none; box-shadow: none; border-radius: 0; overflow: visible; filter: drop-shadow(0 10px 24px rgba(24, 26, 48, .16)); }
.layout-heart .cell {
  border-radius: 0; background: none;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12 21s-8.5-5.4-10.4-11A5.7 5.7 0 0 1 12 5.6 5.7 5.7 0 0 1 22.4 10C20.5 15.6 12 21 12 21z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 22'%3E%3Cpath d='M12 21s-8.5-5.4-10.4-11A5.7 5.7 0 0 1 12 5.6 5.7 5.7 0 0 1 22.4 10C20.5 15.6 12 21 12 21z'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* Tilt classes only rotate: they never touch display, so a .collage (grid)
   can carry one without losing its layout. Inline wrappers get display:block
   from their width class. */
.tilt-n2 { transform: rotate(-2deg); }
.tilt-n3 { transform: rotate(-3deg); }
.tilt-n4 { transform: rotate(-4deg); }
.tilt-n6 { transform: rotate(-6deg); }
.tilt-p2 { transform: rotate(2deg); }
.tilt-p3 { transform: rotate(3deg); }
.w-50, .w-70, .w-96, .w-110, .w-140, .w-150, .w-170, .w-190 { display: block; }
.w-50 { width: 50px; } .w-70 { width: 70px; } .w-96 { width: 96px; } .w-110 { width: 110px; }
.w-140 { width: 140px; } .w-150 { width: 150px; } .w-170 { width: 170px; } .w-190 { width: 190px; }
.ar-tall img { aspect-ratio: 7 / 10; }
.ar-wide img { aspect-ratio: 11 / 5; }
.w-50 img, .w-70 img, .w-110 img, .w-140 img, .w-150 img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; object-position: var(--focus, 50% 50%); border-radius: 12px; }
.polaroid { display: block; padding: 6% 6% 22%; background: #fff; border-radius: 8px; box-shadow: var(--sh-md); }
.polaroid img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; object-position: var(--focus, 50% 50%); border-radius: 4px; }

/* ---------- Template cards and carousel ---------- */
.tpl-carousel { display: flex; gap: 16px; width: calc(100% + 2 * var(--gutter)); margin: 0 calc(-1 * var(--gutter)); padding: 6px var(--gutter) 12px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.tpl-carousel::-webkit-scrollbar { display: none; }
.tpl-carousel .tpl-card { flex: 0 0 220px; scroll-snap-align: start; }
.tpl-card { display: flex; flex-direction: column; gap: 10px; }
.tpl-frame { display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1; padding: 22px; border-radius: 24px; transition: transform .15s ease; }
.tpl-card:hover .tpl-frame { transform: translateY(-3px); }
.tpl-frame .collage { width: 100%; }
.tpl-tilt { display: block; width: 100%; }
/* Tall ratios are sized by height so every card frame stays square. */
.tpl-tilt .ar-4-5 { width: 80%; margin: 0 auto; }
.tpl-tilt .ar-a4 { width: 70.7%; margin: 0 auto; }
.tpl-tilt .ar-9-16 { width: 56.25%; margin: 0 auto; }
.tpl-tilt .ar-cover { width: 100%; }
.tpl-meta { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; padding: 0 4px; }
.tpl-meta .tag { flex: none; margin-top: 1px; }
.tpl-name { font-weight: 700; font-size: 15px; }
.tpl-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 14px; }

/* ---------- Auto collage section ---------- */
.auto-grid { display: flex; flex-direction: column; gap: 24px; }
.auto-copy { display: flex; flex-direction: column; gap: 16px; }
.auto-copy .eyebrow, .auto-copy .btn { align-self: flex-start; }
.checks { display: flex; flex-direction: column; gap: 10px; }
.checks li { display: flex; gap: 12px; align-items: flex-start; font-weight: 600; color: var(--ink-soft); font-size: 15px; }
.checks .ico { color: var(--teal); margin-top: 2px; }
.auto-visual { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.photo-pile { display: none; }
.pile-arrow { display: none; }
.proposal-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; width: 100%; }
.proposal-grid .proposal .badge { height: 26px; }

/* ---------- Bento ---------- */
.bento { display: flex; flex-direction: column; gap: 14px; }
.bento-card { display: flex; flex-direction: column; gap: 18px; align-items: center; text-align: center; padding: 24px; border-radius: 24px; transition: transform .15s ease; }
.bento-card:hover { transform: translateY(-3px); }
.bento-visual { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 8px 0; }
.bento-text { display: flex; flex-direction: column; gap: 6px; }
.bento-text .muted { font-size: 14px; line-height: 1.5; }
.bento-trio .w-150, .bento-trio .w-96 { display: none; }
.gradient-frame { display: block; padding: 10px; border-radius: 16px; background: linear-gradient(135deg, #5b8cff, #22c7a0); box-shadow: var(--sh-md); }
/* The sticker sits on the polaroid like a real label: bottom-left corner, overlapping the frame. */
.polaroid-wrap { position: relative; }
.sticker-text { position: absolute; left: -22px; bottom: 18px; padding: 8px 14px; background: #fff; border-radius: 12px; box-shadow: var(--sh-md); font-weight: 800; font-size: 18px; color: var(--accent); white-space: nowrap; }
.bento-sizes { align-items: flex-end; gap: 8px; }

/* ---------- Showcase ---------- */
.showcase { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 16px; align-items: center; }
.show-item { position: relative; display: block; }
.show-item .badge { position: absolute; left: 10px; bottom: 10px; height: 26px; font-size: 11px; }

/* ---------- Steps, trust, FAQ ---------- */
.steps { display: flex; flex-direction: column; gap: 14px; margin-top: 24px; }
.step { display: flex; gap: 16px; padding: 22px; background: #fff; border-radius: 22px; box-shadow: var(--sh-md); }
.step .round-ico { width: 48px; height: 48px; }
.step h3 { margin-bottom: 6px; }
.step p { color: var(--ink-soft); font-size: 15px; line-height: 1.55; }
.trust { display: flex; flex-direction: column; gap: 22px; margin-bottom: 48px; }
.trust-item { display: flex; gap: 14px; align-items: flex-start; }
.trust-item .round-ico { width: 44px; height: 44px; }
.trust-item h3 { font-size: 18px; margin-bottom: 6px; }
.trust-item p { color: var(--ink-soft); font-size: 14px; line-height: 1.55; }
.faq-grid { display: flex; flex-direction: column; gap: 16px; }
.faq-grid > div:first-child { display: flex; flex-direction: column; gap: 10px; }
.faq-grid .link-more { align-self: flex-start; margin-top: 4px; }
.faq details { border-top: 1px solid var(--line); }
.faq details:last-child { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 20px 0; font-weight: 700; font-size: 17px; cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .ico { color: var(--muted); }
.faq summary .ico-x, .faq details[open] summary .ico-plus { display: none; }
.faq details[open] summary .ico-x { display: block; }
.faq details p { padding: 0 0 22px; color: var(--ink-soft); line-height: 1.6; max-width: 760px; }

/* ---------- CTA band ---------- */
.cta-band { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 16px; padding: 36px 24px; border-radius: 28px; background: var(--gradient-band); color: #fff; }
.cta-copy { display: flex; flex-direction: column; gap: 16px; order: 2; }
.cta-copy h2 { color: #fff; }
.cta-copy p { color: rgba(255, 255, 255, .85); }
.cta-copy .btn { align-self: flex-start; }
.cta-photos { display: flex; gap: 10px; align-items: center; order: 1; }
.cta-photos > span { display: block; }
.cta-photos img { border-radius: 14px; box-shadow: var(--sh-lg); width: 84px; }
.cta-photos .ar-tall img { width: 76px; }

/* ---------- Page hero bands (inner pages) ---------- */
.page-head { padding: 32px 0 36px; }
.page-head .container { display: flex; flex-direction: column; gap: 14px; }
.breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--muted); }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb li { display: inline-flex; gap: 8px; }
.breadcrumb li + li::before { content: "/"; }
.breadcrumb [aria-current] { color: var(--ink); }
.page-head .lead { max-width: 760px; }
.page-head .btn { align-self: flex-start; }
.page-head-row { display: flex; flex-direction: column; gap: 18px; align-items: flex-start; }
.page-head-row > div { display: flex; flex-direction: column; gap: 14px; }
.page-head .chip-row { margin: 4px 0 0; padding-bottom: 0; }
/* Prose and article pages: head and body share one 800px column. */
.page-head-narrow .container { max-width: 800px; }
.page-head.center .container { align-items: center; }
.page-head.center .btn-row { align-items: center; }

/* ---------- Hubs ---------- */
.cat-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.cat-card { display: flex; flex-direction: column; gap: 14px; padding: 20px; border-radius: 24px; transition: transform .15s ease; }
.cat-card:hover { transform: translateY(-3px); }
.card-visual { display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1; }
.card-visual .collage { width: 100%; }
.card-visual .ar-4-5 { width: 80%; }
.card-visual .ar-a4 { width: 70.7%; }
.card-visual .ar-9-16 { width: 56.25%; }
.card-visual .ar-heart { width: 90%; }
.cat-card-meta { display: flex; align-items: center; gap: 12px; }
.cat-card-meta .round-ico { width: 44px; height: 44px; }
.cat-card-meta .muted { font-size: 13px; }
.feat-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.feat-card { display: flex; flex-direction: column; gap: 16px; padding: 24px; border-radius: 24px; transition: transform .15s ease; }
.feat-card:hover { transform: translateY(-3px); }
.feat-card .collage { width: 100%; max-width: 220px; margin: 0 auto; }
/* A 9:16 strip at 220px is 390px tall and stretches its whole row, leaving a
   hole under the shorter cards. Narrower, it lands at the height of a square. */
.feat-card .ar-9-16 { max-width: 165px; }
.feat-card-wide .collage { max-width: 360px; }
.feat-card .muted { font-size: 14px; }
/* A short visual must not leave a hole under its caption: the caption is
   pushed to the bottom so every card in a row reads on the same line. */
.feat-card .cat-card-meta { margin-top: auto; }

/* ---------- Template category page ---------- */
.howto { display: flex; flex-direction: column; gap: 14px; margin-top: 24px; }
.howto .step { gap: 16px; }
.why-band { display: flex; flex-direction: column; gap: 28px; padding: 36px 24px; border-radius: 28px; }
.why-copy { display: flex; flex-direction: column; gap: 24px; }
.why-band .collage { width: 180px; margin: 0 auto; }
.why-list { display: flex; flex-direction: column; gap: 24px; }
.why-item { display: flex; gap: 14px; align-items: flex-start; }
.why-item .round-ico { width: 44px; height: 44px; }
.why-item h3 { margin-bottom: 6px; }
.why-item p { color: var(--ink-soft); font-size: 15px; line-height: 1.6; }
.related { display: flex; flex-direction: column; gap: 32px; }
.related h2 { font-size: 24px; margin-bottom: 14px; }
.chip-wrap { display: flex; flex-wrap: wrap; gap: 8px; }
.guide-cards { display: flex; flex-direction: column; gap: 12px; }
.guide-card { display: flex; gap: 14px; align-items: center; padding: 12px; background: #fff; border-radius: 18px; box-shadow: var(--sh-sm); }
.guide-card img { width: 64px; height: 64px; object-fit: cover; border-radius: 12px; flex-shrink: 0; }
.guide-card .kicker { display: block; font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.guide-card .title { font-weight: 700; font-size: 15px; }
.guide-card:hover .title { color: var(--accent); }

/* ---------- Feature page ---------- */
.feat-hero { display: flex; flex-direction: column; gap: 24px; }
.feat-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.feat-hero .collage { width: 100%; max-width: 420px; margin: 0 auto; }
.benefits { display: flex; flex-direction: column; gap: 14px; }
.benefit { display: flex; gap: 14px; align-items: flex-start; padding: 24px; background: #fff; border-radius: 22px; box-shadow: var(--sh-md); }
.benefit .round-ico { width: 48px; height: 48px; }
.benefit h3 { margin-bottom: 6px; }
.benefit p { color: var(--ink-soft); font-size: 15px; line-height: 1.6; }

/* ---------- Guides ---------- */
.guide-list { display: flex; flex-direction: column; gap: 14px; }
.guide-item { display: flex; flex-direction: column; gap: 12px; padding: 16px; background: #fff; border-radius: 22px; box-shadow: var(--sh-sm); }
.guide-item .collage { width: 100%; }
.guide-item .title { font-weight: 800; font-size: 18px; letter-spacing: -.02em; }
.guide-item:hover .title { color: var(--accent); }
.guide-item .meta { display: flex; align-items: center; gap: 12px; font-size: 13px; font-weight: 600; color: var(--muted); }
.article-head .tags { display: flex; gap: 8px; }
.article-head .meta { display: flex; gap: 12px; align-items: center; font-size: 13px; font-weight: 600; color: var(--muted); }
.article-head .meta span { display: inline-flex; align-items: center; gap: 5px; }
.article-head .collage { width: 100%; margin: 8px 0 0; }
.cover-img { width: 100%; height: auto; border-radius: 20px; box-shadow: var(--sh-lg); margin-top: 8px; }
.guide-item .cover-img { border-radius: 14px; box-shadow: none; margin: 0; }
.article .table-wrap { overflow-x: auto; margin: 4px 0; }
.article table { border-collapse: collapse; width: 100%; font-size: 15px; }
.article th, .article td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink-soft); }
.article th { font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.article td.px { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink); font-weight: 700; }
.article { padding: 24px 0 48px; }
.article .container { display: flex; flex-direction: column; gap: 16px; max-width: 800px; }
.article h2 { font-size: 26px; margin-top: 20px; }
.article .faq details p { padding-bottom: 18px; }
.article p, .article li { font-size: 16px; line-height: 1.65; color: var(--ink-soft); }
.article strong { color: var(--ink); }
.article ul { display: flex; flex-direction: column; gap: 8px; padding-left: 20px; list-style: disc; }
.toc { display: flex; flex-direction: column; gap: 10px; padding: 18px; border-radius: 18px; background: var(--ground); }
.toc .footer-h { margin-bottom: 2px; }
.toc a { display: flex; gap: 10px; font-weight: 600; font-size: 15px; color: var(--ink-soft); }
.toc a b { color: var(--accent); }
.toc a:hover { color: var(--accent); }
.compare { display: flex; gap: 12px; justify-content: center; padding: 8px 0; }
.compare .collage { width: 48%; }
.caption { font-size: 13px; font-weight: 600; color: var(--muted); text-align: center; }
.callout { display: flex; gap: 12px; padding: 18px; border-radius: 18px; background: var(--lemon); }
.callout .ico { color: var(--amber); margin-top: 2px; }
.callout p { font-size: 15px; line-height: 1.55; }
.size-table { display: flex; flex-direction: column; border-bottom: 1px solid var(--line); }
.size-row { display: flex; align-items: center; justify-content: space-between; padding: 14px 0; border-top: 1px solid var(--line); }
.size-row .name { font-weight: 700; font-size: 15px; color: var(--ink); }
.size-row .px { font-size: 13px; font-weight: 600; color: var(--muted); }
.try-card { display: flex; flex-direction: column; gap: 12px; padding: 24px; border-radius: 22px; background: var(--gradient-band); color: #fff; margin: 12px 0; }
.try-card .eyebrow { background: rgba(255, 255, 255, .2); color: #fff; align-self: flex-start; height: 28px; font-size: 11px; }
.try-card h3 { color: #fff; font-size: 22px; }
.try-card p { color: rgba(255, 255, 255, .85); }
.try-card .btn { align-self: flex-start; }

/* ---------- Prose pages ---------- */
.prose { padding: 24px 0 56px; }
.prose .container { display: flex; flex-direction: column; gap: 16px; max-width: 800px; }
.prose p { font-size: 16px; line-height: 1.65; color: var(--ink-soft); }
.prose h2 { font-size: 24px; margin-top: 16px; }
.prose a.inline { color: var(--accent); font-weight: 700; }

/* ---------- Footer ---------- */
.site-footer { background: var(--ground); padding: 40px 0 100px; }
.footer-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }
.footer-brand { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 14px; }
.footer-brand .btn { align-self: flex-start; }
.footer-brand .muted { font-size: 15px; max-width: 280px; }
.footer-h { font-weight: 800; font-size: 14px; letter-spacing: 0; margin-bottom: 12px; line-height: 1.3; }
.footer-list { display: flex; flex-direction: column; gap: 9px; font-size: 15px; color: var(--ink-soft); }
.footer-list a:hover { color: var(--accent); }
.footer-bottom { display: flex; flex-direction: column; gap: 16px; margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--line); }
.footer-bottom .muted { font-size: 13px; }
.footer-langs { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---------- Sticky mobile CTA ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, .92); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border-top: 1px solid var(--line-2);
}
.sticky-cta .sticky-text { display: flex; flex-direction: column; gap: 2px; }
.sticky-cta .sticky-text b { font-size: 14px; }
.sticky-cta .sticky-text span { font-size: 12px; font-weight: 600; color: var(--muted); }
.sticky-cta .btn { height: 44px; padding: 0 18px; font-size: 14px; }

/* ====================================================================
   Tablet and up
   ==================================================================== */
@media (min-width: 600px) {
  h1 { font-size: 48px; }
  h2 { font-size: 36px; }
  .lead { font-size: 18px; }
  .section { padding: 72px 0; }
  .btn-row { flex-direction: row; width: auto; justify-content: center; }
  .hero { padding-top: 48px; }
  .hero-title { font-size: 52px; }
  .cat-row { justify-content: center; gap: 28px; }
  .cat { font-size: 14px; gap: 10px; }
  .cat-ico { width: 68px; height: 68px; }
  .em-proposals { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .em-proposals .proposal:nth-child(n+4) { display: block; }
  .tpl-carousel .tpl-card { flex-basis: 260px; }
  .tpl-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px 20px; }
  .bento-trio .w-150, .bento-trio .w-96 { display: block; }
  .showcase { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px 24px; }
  .steps { flex-direction: row; }
  .step { flex: 1; padding: 28px; gap: 18px; }
  .step .round-ico { width: 56px; height: 56px; }
  .trust { flex-direction: row; gap: 32px; }
  .trust-item { flex: 1; }
  .cta-band { flex-direction: row; align-items: center; justify-content: space-between; padding: 56px; border-radius: 36px; }
  .cta-copy { order: 1; max-width: 520px; }
  .cta-photos { order: 2; gap: 16px; }
  .cta-photos img { width: 130px; }
  .cta-photos .ar-tall img { width: 120px; }
  .page-head { padding: 48px 0 44px; }
  .cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .feat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .howto { flex-direction: row; }
  .howto .step { flex: 1; }
  .why-band { padding: 56px 44px; }
  /* Three columns beside a visual leave little width, and an icon set to the
     left of the text takes some of it: the disc and the gaps shrink here so
     the copy keeps a readable measure. */
  .why-list { flex-direction: row; gap: 20px; }
  .why-item { flex: 1; gap: 12px; }
  .why-item .round-ico { width: 40px; height: 40px; }
  .related { flex-direction: row; gap: 48px; }
  .related > div { flex: 1; }
  .guide-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .benefits { flex-direction: row; }
  .benefit { flex: 1; padding: 28px; }
  .footer-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px 24px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-bottom { flex-direction: row; align-items: center; justify-content: space-between; }
  .site-footer { padding-bottom: 40px; }
  .sticky-cta { display: none; }
}

/* ====================================================================
   Desktop
   ==================================================================== */
@media (min-width: 900px) {
  :root { --gutter: 40px; }
  .header-row { height: 72px; }
  .brand-name { font-size: 19px; }
  .nav-toggle { display: none; }
  .header-actions .btn-sm { height: 44px; padding: 0 18px; font-size: 15px; }
  .site-nav { display: flex; position: static; flex-direction: row; align-items: center; gap: 2px; padding: 0; background: none; box-shadow: none; }
  .site-nav > a { padding: 10px 14px; font-size: 15px; border-radius: var(--r-pill); }
  .site-nav > a.is-active { background: rgba(29, 29, 31, .06); }
  .lang-current { padding: 10px 12px; font-size: 14px; border-radius: var(--r-pill); }
  .lang-list { display: none; position: absolute; right: 0; top: 100%; flex-direction: column; gap: 2px; min-width: 160px; padding: 8px; background: #fff; border-radius: 16px; box-shadow: var(--sh-md); }
  .lang-list a { border: 0; height: 40px; border-radius: 10px; }
  .lang-list a:hover { background: var(--ground); }
  .lang-menu:hover .lang-list, .lang-menu:focus-within .lang-list { display: flex; }
  .hero { padding-top: 56px; }
  .hero .container.center { gap: 24px; }
  .hero-title { font-size: 68px; }
  .hero-lead { font-size: 21px; }
  .cat-row { gap: 36px; margin-top: 20px; }
  .cat { font-size: 15px; gap: 12px; }
  .cat-ico { width: 76px; height: 76px; }
  .editor-wrap { padding-top: 48px; margin-bottom: -260px; }
  .section-templates { padding-top: 320px; }
  .em-top { height: 58px; padding: 0 18px; }
  .em-doc, .em-actions .chip-sm { display: inline-flex; }
  .em-body { flex-direction: row; height: 582px; }
  .em-rail { display: flex; flex-direction: column; gap: 10px; align-items: center; width: 92px; padding: 14px 12px; border-right: 1px solid var(--line-2); }
  .em-rail-item { display: block; width: 60px; padding: 4px; border-radius: 12px; }
  .em-rail-item.is-on { background: var(--accent-soft); }
  .em-canvas { flex: 1; align-items: center; padding: 24px; }
  .em-panel { width: 316px; padding: 18px; border-left: 1px solid var(--line-2); }
  .em-proposals { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .section-head { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 32px; }
  .section-head.center { flex-direction: column; align-items: center; }
  .section-head .lead { font-size: 18px; }
  .tpl-carousel .tpl-card { flex-basis: 260px; }
  .tpl-frame { padding: 26px; }
  .tpl-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px 24px; }
  .auto-grid { flex-direction: row; align-items: center; justify-content: space-between; gap: 48px; }
  .auto-copy { max-width: 470px; gap: 22px; }
  .checks li { font-size: 17px; }
  .auto-visual { flex-direction: row; gap: 24px; }
  .photo-pile { display: block; position: relative; width: 200px; height: 300px; flex-shrink: 0; }
  .photo-pile > span { position: absolute; display: block; }
  .photo-pile img { border-radius: 12px; box-shadow: var(--sh-md); }
  .pile-1 { left: 10px; top: 30px; transform: rotate(-10deg); } .pile-1 img { width: 120px; }
  .pile-2 { left: 40px; top: 90px; transform: rotate(6deg); } .pile-2 img { width: 150px; }
  .pile-3 { left: 0; top: 160px; transform: rotate(-4deg); } .pile-3 img { width: 110px; }
  .pile-arrow { display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; border-radius: 50%; background: #fff; box-shadow: var(--sh-md); color: var(--lilac); flex-shrink: 0; }
  .proposal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; width: 330px; }
  .bento { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
  .bento-card { align-items: stretch; text-align: left; justify-content: space-between; padding: 32px; border-radius: 28px; min-height: 330px; }
  .bento-wide { grid-column: span 2; }
  .bento-visual { flex: 1; }
  .bento-text .h3 { font-size: 24px; }
  .bento-text .muted { font-size: 15px; }
  .showcase { display: flex; flex-wrap: wrap; justify-content: center; gap: 28px 40px; padding: 20px 0; }
  .show-item { width: 280px; }
  .show-item:nth-child(3) { width: 170px; }
  .show-item:nth-child(4) { width: 240px; }
  .show-item:nth-child(6) { width: 300px; }
  .show-item .badge { left: 14px; bottom: 14px; height: 30px; font-size: 12px; }
  .step h3 { font-size: 24px; }
  .step p { font-size: 16px; }
  .faq-grid { display: grid; grid-template-columns: 1fr 2fr; gap: 64px; }
  .faq summary { font-size: 18px; padding: 22px 0; }
  .cta-band { padding: 80px 72px; }
  .cta-copy h2 { font-size: 54px; }
  .cta-copy p { font-size: 19px; }
  .cta-photos img { width: 150px; }
  .cta-photos .ar-tall img { width: 140px; }
  .page-head .container { gap: 18px; }
  .page-head h1 { font-size: 60px; }
  .page-head-row { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: 40px; }
  .cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .feat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .feat-card-wide { grid-column: span 2; flex-direction: row; align-items: center; gap: 40px; }
  .feat-card-wide .collage { flex: 0 0 400px; margin: 0; }
  /* The lead card is twice as wide, so its copy has to grow with it instead of
     leaving a third of the card empty. */
  .feat-card-wide .cat-card-meta { flex: 1; margin-top: 0; }
  .feat-card-wide .cat-card-meta > span:last-child { flex: 1; }
  .feat-card-wide .cat-card-meta .h3 { font-size: 26px; }
  .feat-card-wide .cat-card-meta .muted { font-size: 16px; }
  .why-band { flex-direction: row; align-items: center; gap: 40px; padding: 56px 48px; }
  .why-band .collage { width: 160px; flex-shrink: 0; }
  .why-band .why-copy { gap: 36px; }
  .guide-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
  .feat-hero { flex-direction: row; align-items: center; justify-content: space-between; gap: 56px; }
  .feat-hero .feat-copy { max-width: 560px; }
  .feat-hero .collage { width: 420px; margin: 0; }
  .article h2 { font-size: 30px; }
  .footer-grid { grid-template-columns: 1.2fr repeat(4, minmax(0, 1fr)); gap: 40px; }
  .footer-brand { grid-column: auto; }
  .site-footer { padding: 64px 0 40px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn, .cat-ico, .tpl-frame, .bento-card, .cat-card, .feat-card { transition: none; }
}

/* --- Photo handoff: drop on the home page, land in the editor ------------
   The file input is moved off screen rather than display:none, because a
   display:none input cannot be opened by a click() in every browser, and the
   button is the only thing that opens it. */
.drop-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); border: 0; }
.drop-hint { margin: 10px 0 0; font-size: 14px; color: var(--muted); }
/* Empty until something is said, and it must not reserve space while empty:
   the hint above would jump every time a message appears and clears. */
.drop-status { margin: 8px 0 0; font-size: 14px; color: var(--ink-soft); min-height: 0; }
.drop-status:empty { display: none; }

.drop-overlay {
  position: fixed; inset: 0; z-index: 60; display: none;
  align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--ink) 72%, transparent);
  padding: 24px; text-align: center;
}
.drop-overlay span {
  display: block; max-width: 20ch;
  font-size: clamp(24px, 5vw, 40px); font-weight: 700; line-height: 1.2;
  color: var(--surface);
  border: 3px dashed var(--surface); border-radius: var(--r-card);
  padding: 40px 32px;
}
/* The overlay swallows pointer events so the drop lands on the document
   handler wherever the cursor is, rather than on whatever is underneath. */
body.dragging .drop-overlay { display: flex; }
body.dragging { cursor: copy; }

@media (min-width: 720px) {
  .drop-hint { font-size: 15px; }
}

.axis-body { max-width: 68ch; margin-bottom: 26px; }
.axis-body p:last-child { margin-bottom: 0; }

/* --- Templates pages: ONE left edge -------------------------------------
   The hub mixed two container widths: headings and card grids in the 1200px
   container, prose in .article's 800px one, which is centred. An 800 centred
   inside a 1200 starts 200px further right, so every text block sat off to
   the side of the thing it described. Measured 2026-08-26 after David saw it.

   So: everything uses the normal container, and readable line length comes
   from a max-width that is NOT centred. .copy carries the article's typography
   without its container. */
.copy { max-width: 68ch; }
.copy p, .copy li { font-size: 16px; line-height: 1.65; color: var(--ink-soft); }
.copy > * + * { margin-top: 16px; }
.copy strong { color: var(--ink); }
.copy ul, .copy ol { display: flex; flex-direction: column; gap: 10px; padding-left: 22px; }
.copy ul { list-style: disc; }
.copy ol { list-style: decimal; }
.copy > *:first-child { margin-top: 0; }
/* 🔴 A .copy that FOLLOWS a heading needs its own gap. `.copy > * + *` spaces
   the children of a copy block against each other, and `:first-child` removes
   the top margin of the first one - correct inside the block, and it leaves the
   block itself glued to whatever precedes it. On the gallery section that is an
   h2, so the heading sat flush on its own intro line. Caught by the vertical
   rhythm check, not by eye: it reads as merely tight until measured. */
h2 + .copy, h3 + .copy { margin-top: 12px; }
/* Tables need the full width, not the reading width. */
.copy .table-wrap { max-width: none; overflow-x: auto; }
.copy table { border-collapse: collapse; width: 100%; font-size: 15px; }
.copy th, .copy td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
.copy thead th { font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.copy td.px { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 600; color: var(--ink); }

/* An axis: heading, then the one line that says when to browse this way, then
   the explanation, then the cards. All on the same left edge. */
.axis-head { margin-bottom: 20px; }
.axis-head .copy { margin-bottom: 0; }

/* --- Vertical rhythm on the templates pages -----------------------------
   Measured in the browser on 2026-08-26 after David pointed at it, and the
   measurement found three defects rather than the one that was visible:
   sections at 34/0, 30/72 and 14/72 top-to-bottom padding, and three headings
   sitting 0px above the text under them.

   The rule this settles on: WHERE THE BACKGROUND CHANGES, the padding has to
   be symmetric, because the band edge makes any difference obvious. Where it
   does not change, a deliberate group (an intro and the grid it introduces)
   may be tighter, and nobody can see the asymmetry because there is no edge
   to compare it against. */
.section-tight { padding: 56px 0 0; }
.section-tight + .section { padding-top: 26px; }

.tpl-sections { padding: 72px 0; }
.tpl-sections h2 { margin: 0 0 12px; }
.tpl-sections h2 + .copy { margin-bottom: 34px; }
.tpl-sections .copy:last-child { margin-bottom: 0; }
.tpl-sections h2 ~ h2 { margin-top: 6px; }

/* The line under an axis heading is a caption for it, so it sits close to the
   heading and apart from the paragraph below. */
.axis-head h2 { margin: 0 0 4px; }
.axis-when { margin: 0 0 14px; font-weight: 600; color: var(--muted); font-size: 15px; }

/* Published collage gallery (includes/collages.php).
   A collage is judged on its own proportions, so the cell must not impose any:
   the images keep their aspect and the row heights follow. auto-fill with a
   minimum rather than a fixed column count, because these pages are read on a
   phone far more often than on a desktop. */
/* 🔴 COLUMNS, NOT GRID, and the reason is the content. Collages keep their own
   proportions on purpose, so a row of them is a row of different heights and a
   grid leaves a ragged band of empty background under every row. With forty
   images that is most of the page. CSS columns pack them by height instead,
   which is what a gallery of mixed shapes wants and what a grid cannot do.

   The cost is the reading order: columns run down before across. For a gallery
   that is acceptable - nobody reads a wall of pictures in sequence - and it
   would not be for anything where order carries meaning. */
.collage-gallery {
  columns: 2;
  column-gap: 14px;
  margin-top: 20px;
}
.collage-item {
  break-inside: avoid;
  margin: 0 0 14px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--ground);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
}
.collage-item img { display: block; width: 100%; height: auto; }
.collage-item figcaption {
  padding: 8px 10px 10px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-soft);
}
@media (min-width: 700px) { .collage-gallery { columns: 3; column-gap: 18px; } }
@media (min-width: 1000px) { .collage-gallery { columns: 4; column-gap: 18px; } }

/* The image viewer (assets/js/viewer.js). Attaches to any [data-viewer]. */
.viewer-open { overflow: hidden; }
.viewer {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 16px;
  background: rgba(16, 16, 20, .93);
  /* The backdrop is nearly opaque rather than a light wash: a collage is itself
     a page of small pictures, and a translucent overlay would show the gallery
     through the very thing it is meant to isolate. */
}
.viewer[hidden] { display: none; }
.viewer-stage {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-width: 0;
  min-height: 0;
  height: 100%;
}
.viewer-stage img {
  max-width: 100%;
  /* Room for the caption and the counter, taken from the height rather than
     letting the image push them off the screen on a phone in landscape. */
  max-height: calc(100vh - 130px);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 8px;
  background: rgba(255, 255, 255, .04);
}
.viewer-stage figcaption {
  color: rgba(255, 255, 255, .82);
  font-size: 14px;
  text-align: center;
  max-width: 60ch;
}
/* 🔴 IN THE FLOW, NOT ABSOLUTE. Positioned at the bottom of the overlay it sat
   UNDER the action button, which is centred in the stage - two elements placed
   by different systems, so nothing could keep them apart. Inside the stage they
   are laid out by the same flex column and an overlap is impossible rather than
   merely unlikely. */
.viewer-count {
  margin: 0;
  text-align: center;
  color: rgba(255, 255, 255, .55);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.viewer-close, .viewer-nav {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, .1);
  color: #fff;
  cursor: pointer;
  transition: background .15s ease;
}
.viewer-close:hover, .viewer-nav:hover { background: rgba(255, 255, 255, .2); }
.viewer-close:focus-visible, .viewer-nav:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.viewer-close svg, .viewer-nav svg { width: 22px; height: 22px; }
.viewer-close {
  position: absolute;
  top: 14px;
  right: 14px;
}
/* 🔴 EXPLICIT ROWS, because auto-placement is SPARSE by default. With prev at
   column 1 and next at column 3, the browser fills row 1 with both, then finds
   column 2 of row 1 already passed and drops the stage into row 2 - so the
   picture sat below the arrows and the next button fell off the viewport.
   Measured, not guessed: the capture showed prev alone in the top left corner.
   Naming the row for all three removes the guesswork entirely. */
.viewer-prev { grid-column: 1; grid-row: 1; }
.viewer-next { grid-column: 3; grid-row: 1; }
.viewer-nav[hidden] { visibility: hidden; display: grid; }

/* On a phone the arrows would eat the picture, so they sit over it at the
   bottom, where a thumb reaches and where they cover background rather than
   subject. */
@media (max-width: 640px) {
  .viewer { grid-template-columns: 1fr; padding: 10px; }
  .viewer-stage { grid-column: 1; }
  .viewer-stage img { max-height: calc(100vh - 170px); }
  .viewer-prev, .viewer-next {
    position: absolute;
    bottom: 40px;
    grid-column: 1;
  }
  .viewer-prev { left: 22px; }
  .viewer-next { right: 22px; }
}

/* An item that opens the viewer is a link; it must still look like the picture
   it wraps and say it can be clicked. */
/* 🔴 THE LINK THAT WRAPS THE IMAGE, and only it. Written as `.collage-item a`,
   it also caught the action template inside the same figure and gave it
   display: block - which beat `[data-viewer-action] { display: none }` on
   specificity and painted a full-width button under all forty collages. My own
   rule, for a different purpose, one selector too wide. Same shape as the cell
   skew limit that started judging layouts: right rule, wrong domain. */
.collage-item > a[data-viewer-item] { display: block; text-decoration: none; }
.collage-item > a[data-viewer-item]:focus-visible { outline: 2px solid var(--coral); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .viewer-close, .viewer-nav { transition: none; }
}

/* The viewer's action slot: whatever the page put on the item. */
.viewer-action { display: flex; gap: 10px; }
.viewer-action[hidden] { display: none; }

/* 🔴 AN ACTION IS A TEMPLATE, NOT A BUTTON. It is declared inside the item and
   only ever shown as a clone inside the overlay. The `hidden` attribute alone
   did not hold it: `.btn` sets display: inline-flex, which beats the attribute
   default, so every card in the gallery grew a full-width button under it -
   forty of them on a page. Hiding by the attribute that MARKS it as a template
   cannot be forgotten the way a class can, and the clone drops the attribute,
   so nothing has to un-hide it. */
[data-viewer-action] { display: none; }
.viewer-action .btn { white-space: nowrap; }

/* The viewer's loading state: the stage is hidden as a whole until the picture
   is there, so the reader never watches it assemble itself. */
.viewer.is-loading .viewer-stage > *:not(.viewer-spin) { visibility: hidden; }
.viewer-spin {
  display: none;
  width: 34px; height: 34px;
  border: 3px solid rgba(255, 255, 255, .25);
  border-top-color: #fff;
  border-radius: 999px;
  animation: viewer-spin 700ms linear infinite;
}
.viewer.is-loading .viewer-spin { display: block; }
@keyframes viewer-spin { to { transform: rotate(360deg); } }
/* A reader who asked for no motion gets a still ring rather than nothing: the
   signal is "something is happening", and a frozen mark still says it. */
@media (prefers-reduced-motion: reduce) {
  .viewer-spin { animation: none; }
}
