/* ============================================================
   KAIROS · Design System  (mobile-first, built to the prototype)
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Noto+Sans+Hebrew:wght@300;400;500;600;700;800&family=Heebo:wght@300;400;500;600;700;800&display=swap');

:root{
  --bg:        #FAF9F7;
  --paper:     #FFFFFF;
  --ink:       #141414;
  --ink-2:     #2E2E2E;
  --wash:      #F4F1ED;

  --clay:      #C1705B;   /* the brand terracotta: rules, icons, dots, tints */
  /* White text on #C1705B measures 3.66:1, under the 4.5 that normal
     text needs — and that is the main call-to-action on every screen.
     This deeper mix reads at 4.88:1 and is used ONLY where white sits
     on top of it, so badges, hearts and hairlines keep the brand tone. */
  --clay-a11y: #AC5A45;
  --clay-txt:  #B45F45;   /* terracotta text on white */
  --clay-deep: #A85742;
  --clay-soft: #F7EAE4;

  --t1:        #141414;
  --t2:        #6B6B6B;
  /* was #9A938C: 2.69:1 on the tinted panel and 3.03:1 on white, both
     under the 4.5 normal text needs. Captions, hints and timestamps
     all use this. */
  --t3:        #736B63;
  --on-dark:   #FFFFFF;
  --on-dark-2: #BDB6B0;

  --line:      #E8E3DD;
  --line-2:    #F0EBE5;
  /* Used by .sheet__grip and the .sw toggle track. It was referenced
     in three places but never declared, so both rendered transparent —
     the settings toggles had no visible "off" state. */
  --line-strong: #D5CEC5;
  --ok:        #3DBE5F;   /* the green tick from the prototype */

  /* Noto Sans Hebrew is the brand face. Heebo stays loaded as the
     fallback and as a choice in /admin/ → טיפוגרפיה. */
  --f-body:  'Noto Sans Hebrew', 'Heebo', system-ui, sans-serif;
  --f-serif: 'Cormorant Garamond', Georgia, serif;

  --r-card:16px; --r-input:10px; --r-btn:10px; --r-pill:999px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --header-h:68px;

  /* ------------------------------------------------------------
     THE PARTS THE ADMIN PANEL DRIVES

     Everything above is the design as shipped. The sizes below are
     the same design expressed as variables, because /admin/ can
     change them: assets/js/theme.js writes these onto <html>, which
     out-ranks this block whatever order the files loaded in.

     They keep their fallbacks so that a page renders correctly with
     theme.js absent — PREVIEW.html is exactly that case.
     ------------------------------------------------------------ */
  --fs-base:15px;      /* body text                     */
  --fs-h2:26px;        /* screen titles                 */
  --fs-hero-m:40px;    /* entry headline, phone         */
  --fs-hero-d:68px;    /* entry headline, desktop       */
  --fs-logo:23px;      /* the wordmark                  */
  --hero-veil:.72;     /* 0–1, how dark the entry scrim */
  --moon:#C1705B;      /* the coral disc behind the statues */
  /* two aliases: later blocks in this file reach for these names */
  --clay-btn:#C1705B;
  --clay-text:#B45F45;
}

*,*::before,*::after{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }
body{
  font-family:var(--f-body); background:var(--bg); color:var(--t1);
  font-size:var(--fs-base,15px); line-height:1.6; direction:rtl;
  -webkit-font-smoothing:antialiased; overflow-x:clip;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; }
input,select,textarea{ font:inherit; }

/* Anything the browser scrolls to itself — a focused input, an anchor,
   scrollIntoView — stops at the top of the viewport, which on a page
   with a sticky header is UNDERNEATH it. The field you just tapped is
   then covered by the header, and the next tap where you can see it
   lands on the header instead. scroll-padding-top tells the browser
   where the usable top of the page really is. */
html{ scroll-padding-top:calc(var(--header-h) + 12px); }
/* The editor stacks a second sticky strip (title + section chips)
   under the header, and pins a footer of buttons over the bottom, so
   BOTH ends of its viewport are covered. Without the bottom half, a
   field scrolled to the bottom edge sits under the footer and the tap
   meant for it presses "השלב הבא" instead. */
html:has(.ed){
  scroll-padding-top:calc(var(--header-h) + 104px);
  scroll-padding-bottom:calc(96px + env(safe-area-inset-bottom));
}

/* ---------------- header ---------------- */
/* The sticky element has to be #hd, not .hd. UI.mount() injects the
   header into <div id="hd">, so a sticky .hd is the only child of a
   wrapper exactly its own height — it has nowhere to travel and
   scrolls away like a static box. Everything below that sticks to
   var(--header-h) then floats over a transparent gap. Sticking the
   wrapper, whose containing block is <body>, is what was meant. */
#hd{ position:sticky; top:0; z-index:50; }
/* The header is drawn by UI.mount() once the scripts arrive, into a
   <div id="hd"> that is EMPTY in the HTML. On a laptop that happens
   before the first paint and nobody notices. On a phone on mobile
   data the page paints first — breadcrumb, gallery, headline — and
   then the header lands on top of it and shoves the whole page down
   68px. That was the jump. Every page that has this slot fills it, at
   the same height at every width, so the space is simply held open
   from the first byte. */
#hd{ min-height:var(--header-h); }
.hd{
  height:var(--header-h);
  display:flex; align-items:center; justify-content:space-between; padding:0 18px;
  background:var(--paper); border-bottom:1px solid var(--line-2);
}
.hd__logo{
  display:flex; align-items:center; justify-content:center;
  font-family:var(--f-serif); font-size:var(--fs-logo,23px); letter-spacing:.13em;
  font-weight:500; direction:ltr; color:var(--ink); line-height:1;
}
/* the real wordmark, once app/assets/img/logo.svg exists */
.hd__logo__img{ height:26px; width:auto; display:block; }
.hd__logo.has-img .hd__logo__t{ display:none; }
.hd__ic{
  width:26px; height:26px; display:flex; align-items:center; justify-content:center;
  background:none; border:none; cursor:pointer; color:var(--ink);
  position:relative;
  /* Safari gives every <button> side padding of its own; Chrome does
     not. Inside a 26px box that left the icon 14px to live in, and
     because the SVG is a flex item it shrank to fit — the menu drawn
     at half its width on an iPhone and at full size everywhere a
     developer would ever look. */
  padding:0; -webkit-appearance:none; appearance:none;
}
.hd__ic svg{ flex:none; display:block; }
/* The same Safari trap, everywhere else a button is a fixed-size box
   around an icon. iOS gives <button> its own side padding — more than
   desktop Safari, far more than Chrome — and a flex-centred SVG shrinks
   into whatever is left. At 34px wide that was the "tiny dot" in the
   gallery's eye button; at 26px it was nothing at all. Found by
   listing every button class with a fixed width and height and no
   padding of its own; none of these has text that needs the room. */
.gal__nav, .gal__zoom, .sumcard__edit, .c2__pvtab, .dp__nav, .adm-gal__add, .sw{
  padding:0; -webkit-appearance:none; appearance:none;
}
.gal__nav svg, .gal__zoom svg, .sumcard__edit svg, .c2__pvtab svg, .dp__nav svg{ flex:none; }
/* The icon stays 26px because that is the size it was drawn at. What
   grows is the part a thumb has to hit: 26px is a little over half
   the 44px Apple and Google both call the minimum, and these three —
   menu, account, back — are the whole navigation of a phone-first
   product. A pseudo-element does it without touching the layout, so
   nothing moves by a pixel. The header never renders two of these
   side by side, so the enlarged areas cannot overlap each other. */
.hd__ic::after{
  content:""; position:absolute; top:50%; left:50%;
  width:44px; height:44px; transform:translate(-50%,-50%);
}
.hd__side{ display:flex; align-items:center; gap:14px; }
/* ---------------- layout ---------------- */
.wrap{ padding:26px 18px 40px; max-width:520px; margin:0 auto; }
.wrap--flush{ padding:0; max-width:520px; margin:0 auto; }

/* ---------------- type ---------------- */
.h1{ font-size:33px; font-weight:700; line-height:1.24; letter-spacing:-.01em; margin:0; }
.h2{ font-size:var(--fs-h2,26px); font-weight:700; line-height:1.3; margin:0; }
.h3{ font-size:17px; font-weight:600; margin:0; }
.lead{ color:var(--t2); font-size:15px; line-height:1.65; margin:12px 0 0; }
.clay{ color:var(--clay-txt); }
.serif{ font-family:var(--f-serif); }
.center{ text-align:center; }
.muted{ color:var(--t3); font-size:13px; }

/* ---------------- stepper ---------------- */
.step{ display:flex; align-items:flex-start; justify-content:center; margin:6px 0 30px; }
.step__i{ display:flex; flex-direction:column; align-items:center; gap:7px; width:76px; }
.step__n{
  width:29px; height:29px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:14px; font-weight:600;
  background:var(--paper); border:1px solid var(--line); color:var(--t3);
}
.step__i.is-on .step__n{ background:var(--clay-a11y); border-color:var(--clay-a11y); color:#fff; }
.step__i.is-done .step__n{ background:var(--paper); border-color:var(--clay); color:var(--clay-txt); }
.step__l{ font-size:11px; color:var(--t3); white-space:nowrap; }
.step__i.is-on .step__l{ color:var(--t1); font-weight:500; }
.step__bar{ flex:1; height:1px; background:var(--line); margin-top:14px; max-width:52px; }
.step__bar.is-done{ background:var(--clay); }

/* ---------------- buttons ---------------- */
.btn{
  display:flex; align-items:center; justify-content:center; gap:9px;
  width:100%; padding:15px 22px; border-radius:var(--r-btn);
  border:1px solid transparent; background:none;
  font-size:15.5px; font-weight:500; cursor:pointer;
  transition:background .2s var(--ease), border-color .2s var(--ease), opacity .2s var(--ease);
}
.btn:active{ opacity:.85; }
.btn--clay{ background:var(--clay-a11y); color:#fff; }
.btn--clay:hover{ background:var(--clay-deep); }
.btn--dark{ background:var(--ink); color:#fff; }
.btn--white{ background:var(--paper); color:var(--t1); border-color:var(--line); }
.btn--out{ background:transparent; border-color:var(--line); color:var(--clay-txt); }
.btn--pill{ border-radius:var(--r-pill); padding:17px 22px; }
.btn--sm{ padding:11px 16px; font-size:13.5px; }
.btn[disabled]{ opacity:.45; pointer-events:none; }
.link{ color:var(--clay-txt); cursor:pointer; background:none; border:none; padding:0; }
.link--u{ text-decoration:underline; text-underline-offset:2px; }

/* ---------------- fields ---------------- */
.f{ margin-bottom:13px; }
.f__lab{ display:block; font-size:14px; font-weight:600; margin-bottom:8px; }
.f__in{
  width:100%; padding:16px 17px;
  background:var(--paper); border:1px solid var(--line); border-radius:var(--r-input);
  font-size:15px; color:var(--t1); transition:border-color .18s var(--ease);
}
.f__in::placeholder{ color:var(--t3); }
.f__in:focus{ outline:none; border-color:var(--clay); box-shadow:0 0 0 3px rgba(193,112,91,.10); }

.f--ic{ position:relative; }
/* The page is always RTL and the icon always sits on the left, so these use
   physical sides on purpose: a field with dir="ltr" (card number, email)
   would otherwise flip its padding and run the text under the icon. */
.f--ic .f__in{ padding-left:50px; padding-right:17px; }
.f__ic{
  position:absolute; left:15px; top:50%; transform:translateY(-50%);
  width:22px; height:22px; display:flex; align-items:center; justify-content:center;
  color:var(--t3); pointer-events:none;
}
.f__ic--tap{ pointer-events:auto; cursor:pointer; }

.f--float{ position:relative; margin-bottom:13px; }
.f--float .f__mini{
  position:absolute; top:10px; right:17px;
  font-size:11px; color:var(--t3); line-height:1;
}
.f--float .f__in{ padding:29px 17px 12px; }
.f--float.f--ic .f__in{ padding-left:50px; padding-right:17px; }

.row-2{ display:grid; grid-template-columns:1fr 1fr; gap:11px; }

/* ---------------- cards ---------------- */
.card{ background:var(--paper); border:1px solid var(--line); border-radius:var(--r-card); padding:26px 22px; }
.card--dark{ background:var(--ink); border-color:var(--ink); color:var(--on-dark); position:relative; }

/* ---------------- pricing (/setup/package) ----------------
   The same cards as the marketing site's pricing block, so a couple
   who clicks through from kairos.co.il lands on the page they were
   just looking at. Values copied from that embed (#kairos-pricing),
   prefixed .kp- here as there. Self-serve packages are the cards;
   a contact package (בהתאמה אישית) is the row underneath them,
   because it is a conversation, not a third price to compare. */
.kp-plans{ display:grid; grid-template-columns:1fr; gap:20px; align-items:stretch; }
.kp-plan{
  position:relative; min-width:0; display:flex; flex-direction:column; cursor:pointer;
  border:1px solid #e7dfd9; border-radius:20px; padding:26px 24px;
  background:linear-gradient(145deg,#fff 20%,#fcf8f5 100%); color:#292624;
  box-shadow:0 18px 44px -24px #533b2b33, 0 2px 5px #533b2b06;
  transition:box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.kp-featured{
  background:radial-gradient(ellipse at 100% 0%, #403731 0%, #292725 65%);
  color:#fff; border-color:#453b34;
}
/* the package that is chosen: a ring in the accent, nothing louder */
.kp-plan.is-selected{ border-color:#b7705a; box-shadow:0 0 0 2px #b7705a, 0 18px 44px -24px #533b2b33; }
.kp-plan h2, .kp-service h2{
  font:500 22px/1.4 var(--f-body); letter-spacing:-.02em; margin:0 0 12px; color:inherit;
}
.kp-desc{ font-size:15px; line-height:1.75; color:#746b65; margin:0; max-width:380px; text-wrap:pretty; }
.kp-featured .kp-desc{ color:#d2cbc6; }
.kp-price{ display:flex; align-items:baseline; gap:12px; margin:22px 0 0; }
.kp-amount{ font:500 38px/1.1 var(--f-body); letter-spacing:-.04em; direction:ltr; white-space:nowrap; }
.kp-once{ font-size:12px; color:#80756d; }
.kp-featured .kp-once{ color:#c5bcb5; }
.kp-rule{ height:1px; background:#eae2dc; margin:23px 0; }
.kp-featured .kp-rule{ background:#ffffff21; }
.kp-plan ul{ list-style:none; padding:0; margin:0 0 30px; display:grid; gap:13px; }
.kp-plan li{ position:relative; padding-inline-start:26px; font-size:15px; line-height:1.65; }
/* the tick is drawn, not an icon: two borders of a rotated box. Physical
   `right` on purpose — in this RTL page that is the start of the line. */
.kp-plan li::before{
  content:""; position:absolute; right:2px; top:8px; width:6px; height:11px;
  border-right:1.6px solid #b7705a; border-bottom:1.6px solid #b7705a; transform:rotate(45deg);
}
.kp-featured li::before{ border-color:#e2b49f; }
.kp-button{
  display:flex; justify-content:center; align-items:center; text-align:center; width:100%;
  min-height:50px; padding:12px 22px; margin-top:auto; border-radius:10px;
  border:1px solid #b7705a; background:#b7705a; color:#fff;
  font:500 15px/1.5 var(--f-body); cursor:pointer; text-decoration:none;
}
.kp-button:focus-visible, .kp-plan:focus-visible{ outline:2px solid #b7705a; outline-offset:5px; }
.kp-plan.is-selected .kp-button::before{ content:"✓"; margin-inline-end:8px; }
.kp-service{
  margin-top:28px; padding-top:26px; border-top:1px solid #e8dfd7;
  display:flex; flex-direction:column; align-items:flex-start; gap:20px;
}
.kp-service-copy{ max-width:640px; min-width:0; }
.kp-service h2{ font-size:20px; margin-bottom:8px; }
.kp-service p{ font-size:15px; line-height:1.8; color:#746b65; margin:0; text-wrap:pretty; }
.kp-contact{ background:#fff; color:#b7705a; min-height:48px; }
/* a design this package does not include */
.kp-off{ opacity:.5; cursor:default; }
.kp-lock{ font-size:12px; color:var(--t3); margin-top:auto; }
.kp-featured .kp-lock{ color:#c5bcb5; }

.sticky{
  position:fixed; inset-inline:0; bottom:0; z-index:60;
  max-width:520px; margin-inline:auto;      /* match .wrap, don't span the viewport */
  background:var(--ink); color:var(--on-dark);
  padding:14px 18px calc(14px + env(safe-area-inset-bottom));
  border-radius:16px 16px 0 0;
}
.sticky__t{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sticky__t{ text-align:center; font-size:14px; margin-bottom:11px; }
.has-sticky{ padding-bottom:132px; }

/* ---------------- filters ---------------- */
.chips{ display:flex; gap:9px; overflow-x:auto; padding:2px 0 4px; scrollbar-width:none; }
.chips::-webkit-scrollbar{ display:none; }
/* collection.html fills its category chips from script; the empty
   row was 6px tall and grew to 48 under the headline, dragging the
   whole catalogue down with it. One row of chips, held open. */
#types{ min-height:48.4px; }
.chip{
  flex:none; padding:9px 19px; border-radius:var(--r-pill);
  background:var(--paper); border:1px solid var(--line);
  font-size:14px; color:var(--t2); cursor:pointer; white-space:nowrap;
}
.chip.is-on{ background:var(--clay-a11y); border-color:var(--clay-a11y); color:#fff; }

.tools{ display:flex; align-items:center; justify-content:space-between; margin:16px 0 18px; }
.tools__btn{ order:1; }      /* filter sits where the page label was */
.tools .muted{ order:2; }
.tools__btn{
  display:flex; align-items:center; gap:9px;
  background:var(--ink); color:#fff; border:none; cursor:pointer;
  padding:11px 18px; border-radius:var(--r-pill); font-size:13.5px;
}

/* ---------------- design grid ---------------- */
.grid{ display:grid; grid-template-columns:1fr 1fr; gap:13px; align-items:stretch; }

/* design card — the image is the product, so it leads */
.dz{
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--paper); border:1px solid var(--line-2); border-radius:16px;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
/* no border colour change on hover — it read as an outline.
   The card just lifts a little and the image breathes. */
.dz:hover{ transform:translateY(-4px); box-shadow:0 14px 30px rgba(60,45,32,.10); }
.dz:active{ transform:translateY(-1px); box-shadow:0 6px 14px rgba(60,45,32,.08); }

.dz__shot{
  position:relative; display:block; aspect-ratio:4/5;
  background:var(--wash); overflow:hidden;
}
.dz__shot img{ width:100%; height:100%; object-fit:cover; transition:transform .55s var(--ease); }
.dz:hover .dz__shot img{ transform:scale(1.045); }

/* preview affordance sits ON the image, where it cannot be mistaken
   for a caption. Text included — an icon alone reads as decoration. */
.dz__peek{
  position:absolute; bottom:9px; inset-inline-start:9px;
  display:inline-flex; align-items:center; gap:5px;
  background:rgba(255,255,255,.95); border:1px solid rgba(0,0,0,.06);
  border-radius:var(--r-pill); padding:8px 13px 8px 11px;
  font-size:11.5px; font-weight:500; color:var(--t1); cursor:pointer;
  box-shadow:0 2px 8px rgba(60,45,32,.10);
  transition:background .2s var(--ease);
}
.dz__peek:hover{ background:#fff; }
.dz__peek svg{ flex:none; }

.dz__body{
  padding:13px 12px 14px; text-align:center;
  display:flex; flex-direction:column; flex:1;
}
.dz__name{ font-family:var(--f-serif); font-style:italic; font-size:20px; font-weight:500; line-height:1.2; }
.dz__tags{
  font-size:11px; color:var(--t3); margin:5px 0 12px;
  min-height:16px; letter-spacing:.01em;
}
.dz__from{ display:block; font-size:11.5px; color:var(--t2); margin:-6px 0 11px; }
.dz .btn--sm{ margin-top:auto; font-size:12.5px; padding:10px 10px; }

/* ============================================================
   ENTRY HERO

   The phone layout, which is what a phone always gets whatever
   the admin panel says: headline first, the two buttons directly
   under the sentence they belong to, and the photograph filling
   the screen behind and below them. The desktop variants are far
   down the file in the BIGGER SCREENS block.

   `--hero-veil` is set by /admin/. It scales the whole scrim
   rather than replacing it, so the gradient keeps its shape —
   heaviest behind the headline, clearing through the middle where
   the figures are, returning at the very bottom.
   ============================================================ */
.hero{
  position:relative; min-height:calc(100svh - var(--header-h));
  background:var(--ink); color:#fff; overflow:hidden;
  display:flex; flex-direction:column; padding:0 26px;
}
.hero__img{ position:absolute; inset:0; z-index:1; background:#1c1a19 center/cover no-repeat; }
.hero__img::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(180deg,
    rgba(16,16,16,calc(var(--hero-veil,.72) * 1.25)) 0%,
    rgba(16,16,16,calc(var(--hero-veil,.72) * 1.02)) 26%,
    rgba(16,16,16,calc(var(--hero-veil,.72) * .42))  55%,
    rgba(16,16,16,calc(var(--hero-veil,.72) * .22))  74%,
    rgba(16,16,16,calc(var(--hero-veil,.72) * .86))  100%);
}

/* The coral disc from the mockup. It sits UNDER the photograph and
   shows through wherever the photograph is faded out — which on a
   phone is nowhere, so it is off here and switched on with the
   split layout. */
.hero__moon{ display:none; }

/* one grid, so the desktop split is a change of columns rather than
   a different set of boxes */
.hero__grid{ position:relative; z-index:2; flex:1; display:flex; flex-direction:column; }
.hero__in{ text-align:center; padding-top:12vh; }
.hero__h{ font-size:var(--fs-hero-m,40px); font-weight:700; line-height:1.22; margin:0; }
/* The accented word, on a dark screen. `--clay-txt` is tuned for
   terracotta text on white and goes muddy here, so the accent is
   lifted toward white — the peach in the mockup. It still follows
   whatever clay the admin panel sets. */
.hero__h .clay{
  color:#D08C74;
  color:color-mix(in srgb, var(--clay) 58%, #fff);
}
.hero__p{ color:#D8D2CC; font-size:14.5px; line-height:1.65; margin:16px auto 26px; max-width:310px; }
.hero__acts{ display:flex; flex-direction:column; gap:12px; }
/* the phone mockup shows the buttons a little inside the screen edge */
.hero__acts .btn{ box-shadow:0 10px 26px rgba(0,0,0,.18); }

/* ---------------- confirmation ---------------- */
.done{
  border-radius:18px; overflow:hidden; position:relative;
  background:var(--paper); text-align:center; min-height:620px;
  display:flex; flex-direction:column;
}
.done__bg{ position:absolute; inset:0; background:center/cover no-repeat; z-index:0; }
.done__in{ position:relative; z-index:2; padding:34px 26px 26px; }
.done__tick{
  width:44px; height:44px; border-radius:50%; background:var(--ink);
  display:flex; align-items:center; justify-content:center; margin:0 auto 14px;
}

/* ---------------- misc ---------------- */
.divider{ display:flex; align-items:center; gap:14px; margin:20px 0; color:var(--t3); font-size:13px; }
.divider::before,.divider::after{ content:''; flex:1; height:1px; background:var(--line); }
.panel-strip{
  display:flex; justify-content:space-between; align-items:center;
  background:var(--ink-2); margin:20px -22px -26px; padding:16px 22px;
  border-radius:0 0 var(--r-card) var(--r-card); font-size:15px;
}
.check{ display:flex; align-items:center; gap:9px; font-size:14px; cursor:pointer; }
.check input{ width:19px; height:19px; accent-color:var(--clay); }
.err{ color:var(--clay-deep); font-size:13.5px; min-height:19px; margin:6px 0 0; }
.spin{ width:18px; height:18px; border:2px solid var(--line); border-top-color:var(--clay);
  border-radius:50%; animation:sp .7s linear infinite; margin:40px auto; }
@keyframes sp{ to{ transform:rotate(360deg); } }
.toast{
  position:fixed; bottom:22px; inset-inline:18px; z-index:200;
  background:var(--ink); color:#fff; padding:14px 20px; border-radius:12px;
  font-size:14px; line-height:1.6; text-align:center;
  opacity:0; transform:translateY(12px);
  pointer-events:none; transition:.28s var(--ease);
  /* a database error is a sentence, not a word — let it wrap, keep it
     centred on wide screens, and make it tappable to dismiss */
  max-width:520px; margin-inline:auto;
  box-shadow:0 10px 30px rgba(20,20,20,.22);
}
.toast.is-on{ opacity:1; transform:none; pointer-events:auto; cursor:pointer; }

@media (min-width:560px){
  .wrap{ padding:34px 26px 60px; }
  .h1{ font-size:37px; }
}
@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* ============================================================
   Design-first flow additions
   ============================================================ */

/* gallery card badge + pagination */
.dz__incl{
  display:inline-block; margin-bottom:9px; font-size:10.5px;
  color:var(--clay-txt); background:var(--clay-soft);
  padding:3px 10px; border-radius:var(--r-pill);
}
.pager{ display:flex; align-items:center; justify-content:center; gap:7px; margin:26px 0 6px; }
.pager button{
  min-width:31px; height:31px; border-radius:50%; border:1px solid var(--line);
  background:var(--paper); color:var(--t2); font-size:13.5px; cursor:pointer;
}
.pager button.is-on{ background:var(--clay-a11y); border-color:var(--clay-a11y); color:#fff; }
.pager button[disabled]{ opacity:.35; pointer-events:none; }

/* ============================================================
   DESIGN DETAIL · the gallery

   A product page for something bought on how it looks needs more
   than one photograph of it. The old page showed exactly one, with
   any extras dumped into a separate strip somewhere below — so the
   second and third views of a design were, in practice, never seen.

   One stage, one strip, and the strip IS the navigation. The arrows
   are for anyone who would rather page than aim, and both they and
   the strip disappear for a design that only has one shot rather
   than offering controls that do nothing.
   ============================================================ */
.gal{
  background:var(--paper); border:1px solid var(--line);
  border-radius:16px; padding:14px 14px 16px;
}
.gal__stage{
  position:relative; background:var(--wash); border-radius:12px;
  aspect-ratio:4/3.4; overflow:hidden;
}
/* every shot side by side; a swipe follows the finger and snaps to
   the next one, and the arrows and thumbnails slide it the same way */
.gal__track{
  display:flex; height:100%; overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x mandatory; overscroll-behavior-x:contain;
  scrollbar-width:none; -webkit-overflow-scrolling:touch; outline:none;
}
.gal__track::-webkit-scrollbar{ display:none; }
.gal__track:focus-visible{ box-shadow:inset 0 0 0 2px var(--clay); border-radius:12px; }
.gal__slide{
  flex:0 0 100%; height:100%; padding:20px;
  display:flex; align-items:center; justify-content:center;
  scroll-snap-align:center;
}
.gal__slide img{
  max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain;
  cursor:zoom-in; -webkit-user-drag:none; user-select:none;
}

/* ---- the control row ----
   Arrows, position and full-view in one line under the picture. They
   used to be three circles floating on the artwork. */
/* Three columns, so the arrows stay dead centre whatever the counter
   says, and the counter sits on the edge instead of floating next to
   them. On a phone the arrows are gone and the counter holds its
   corner rather than drifting into the middle. */
.gal__bar{
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
  margin-top:12px; min-height:34px;
}
.gal__bar__nav{ display:flex; align-items:center; gap:10px; justify-content:center; }
.gal__bar[hidden]{ display:none; }
.gal__nav{
  width:34px; height:34px; border-radius:50%; border:1px solid var(--line);
  background:var(--paper); color:var(--t2); cursor:pointer;
  display:flex; align-items:center; justify-content:center; flex:none;
  transition:background .18s var(--ease), color .18s var(--ease);
}
.gal__nav:hover{ background:var(--wash); color:var(--ink); }
.gal__nav[hidden]{ display:none; }
.gal__count{
  grid-column:1; justify-self:start;
  font-size:12px; color:var(--t3); font-variant-numeric:tabular-nums lining-nums;
  direction:ltr; min-width:44px; text-align:start;
}
/* full view: a labelled button in the row, not an unexplained circle
   in the corner of the photograph */
/* Not pushed to the far edge: on a 664px card that left the arrows on
   one side and this on the other with a canyon between them. */
.gal__zoom{
  margin-inline-start:6px; display:inline-flex; align-items:center; gap:7px;
  height:34px; padding:0 13px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:var(--paper);
  color:var(--t2); font:inherit; font-size:12.5px; cursor:pointer;
  transition:background .18s var(--ease), color .18s var(--ease);
}
.gal__zoom:hover{ background:var(--wash); color:var(--ink); }
.gal__zoom__ic{ display:inline-flex; }

/* On a phone the picture is swiped and the strip is tapped. Two
   chevrons on a 390px screen buy nothing and cost a row of attention. */
@media (hover:none) and (pointer:coarse){
  .gal__nav{ display:none !important; }
}
/* ---- the strip ----
   One box per thumbnail, and the picture is CONTAINED in it. It used
   to be `cover`, so a wide device shot was cropped to a tall sliver
   while a portrait card fitted — the same strip showing two different
   shapes, one of them mangled. Square boxes suit both. */
.gal__thumbs{
  display:flex; gap:8px; margin-top:12px; overflow-x:auto;
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity; scroll-padding-inline:2px; padding-bottom:2px;
  -webkit-mask-image:none; mask-image:none;
  transition:-webkit-mask-image .2s linear;
}
.gal__thumbs::-webkit-scrollbar{ display:none; }
.gal__thumbs[hidden]{ display:none; }
/* the fade is applied to whichever edge still has thumbnails behind
   it — set from script, so it never fades an edge with nothing past it */
.gal__thumbs.has-more-end{
  -webkit-mask-image:linear-gradient(to left, transparent 0, #000 22px, #000 100%);
          mask-image:linear-gradient(to left, transparent 0, #000 22px, #000 100%);
}
.gal__thumbs.has-more-start{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 22px, #000 100%);
          mask-image:linear-gradient(to right, transparent 0, #000 22px, #000 100%);
}
.gal__thumbs.has-more-start.has-more-end{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
          mask-image:linear-gradient(to right, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
}
.gal__th{
  flex:none; width:62px; aspect-ratio:1; padding:5px; cursor:pointer;
  scroll-snap-align:start;
  border:1.5px solid var(--line); border-radius:10px; overflow:hidden;
  background:var(--paper); transition:border-color .18s var(--ease);
}
.gal__th img{ width:100%; height:100%; object-fit:contain; display:block; }
.gal__th.is-on{ border-color:var(--clay); }
/* the live demo, full width under the strip: the page's real promise */
.gal__live{ width:100%; margin-top:16px; }
.gal__live span{ display:inline-flex; margin-inline-end:8px; vertical-align:-3px; }
.gal__note{ font-size:11.5px; color:var(--t3); margin:12px 2px 0; line-height:1.6; }

/* the reassurance card under the gallery */
.lovecard{
  display:flex; align-items:flex-start; gap:14px; margin-top:14px;
  background:var(--paper); border:1px solid var(--line);
  border-radius:16px; padding:16px 18px;
}
.lovecard__ic{
  flex:none; width:44px; height:44px; border-radius:50%;
  display:grid; place-items:center; color:var(--clay); background:var(--wash);
}
.lovecard__t{ font-size:14.5px; font-weight:600; margin:0 0 4px; }
.lovecard__d{ font-size:12.5px; color:var(--t2); line-height:1.65; margin:0; }

/* the pill that appears only on the design already chosen */
.dt__badge[hidden]{ display:none; }
.dt__badge{
  display:inline-block; align-self:flex-start; margin:0 0 10px;
  background:var(--wash); border:1px solid var(--line); border-radius:999px;
  padding:5px 13px; font-size:11.5px; color:var(--t2);
}
.dt__acts{ display:flex; flex-direction:column; gap:10px; margin-top:20px; }
.dt__acts .btn{ width:100%; }
.dt__acts .btn span{ display:inline-flex; margin-inline-end:8px; vertical-align:-3px; }

/* breadcrumb */
.crumb{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-size:12.5px; color:var(--t3); margin-bottom:16px;
}
.crumb a{ color:var(--t2); text-decoration:none; }
.crumb a:hover{ color:var(--ink); text-decoration:underline; }
.crumb b{ color:var(--ink); font-weight:500; }

/* The space above the name used to be the badge's bottom margin, and
   the badge only appears on the design a couple has already chosen —
   so on every other design the name landed hard against the gallery
   card with nothing between them. The gap belongs to the block that
   is always there. 27px rather than 30 because at 30 the italic
   serif on a 390px phone is bigger than the h2 under it. */
.dt__media{ margin-bottom:24px; }
.dt__name{ font-family:var(--f-serif); font-style:italic; font-weight:500;
  line-height:1.2; margin-top:0;
  /* The name used to be one size until 1100px and then jump to 44px.
     Between 768 and 1100 the page is a single 664px column, and a 27px
     italic sitting on top of it read as an afterthought. It now grows
     with the width it has: 27px on a phone, ~40px on that wide single
     column, 44px once the two-column layout starts. */
  font-size:clamp(27px, 1rem + 2.4vw, 44px); }
.dt__tags{ font-size:13px; color:var(--t2); margin-top:6px; }
.dt__desc{ font-size:14px; color:var(--t2); line-height:1.75; margin-top:14px; }
.dt__feats{ display:flex; justify-content:space-between; gap:8px; margin:22px 0 6px; text-align:center; }
.dt__feat{ flex:1; display:flex; flex-direction:column; align-items:center; gap:7px;
  font-size:11.5px; color:var(--t2); line-height:1.35; }
.dt__feat svg{ color:var(--clay); }

/* accordion */
.acc{ border:1px solid var(--line); border-radius:var(--r-input); background:var(--paper); margin-top:18px; }
/* the variant whose heading sits OUTSIDE it: the rows carry their own
   rules, so a box around them is a second frame around a first */
.acc--flat{ border:0; border-radius:0; background:none; margin-top:0; }
.acc--flat .accrow:first-child{ border-top:1px solid var(--line); }
.acc__hd{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  padding:15px 17px; background:none; border:none; cursor:pointer; font-size:14.5px;
}
.acc__bd{ padding:0 17px 16px; display:none; }
.acc.is-open .acc__bd{ display:block; }
.acc.is-open .acc__hd svg{ transform:rotate(180deg); }
.acc__hd svg{ transition:transform .22s var(--ease); color:var(--t3); }

.note{
  background:var(--wash); border-radius:var(--r-input);
  padding:15px 17px; font-size:12.5px; color:var(--t2); line-height:1.7; margin-top:18px;
}

/* ---------- package: design carried forward ---------- */
.chosen{
  display:flex; align-items:center; gap:13px; background:var(--paper);
  border:1px solid var(--line); border-radius:var(--r-input); padding:12px 14px; margin-bottom:22px;
}
.chosen__sh{ width:44px; height:56px; border-radius:7px; background:var(--wash); flex:none;
  display:flex; align-items:center; justify-content:center; overflow:hidden; }
.chosen__sh img{ width:100%; height:100%; object-fit:cover; }
.chosen__n{ font-family:var(--f-serif); font-style:italic; font-size:19px; }
.chosen__s{ font-size:12px; color:var(--t3); }

/* ---------- payment: methods + summary ---------- */
.pay-line{
  display:flex; align-items:center; gap:11px; padding:14px 16px;
  border:1px solid var(--line); border-radius:var(--r-input);
  background:var(--paper); margin-bottom:9px; cursor:pointer; font-size:14.5px;
}
.pay-line.is-on{ border-color:var(--clay); background:var(--clay-soft); }
.pay-line input{ accent-color:var(--clay); width:17px; height:17px; }
.pay-line__logos{ margin-inline-start:auto; display:flex; gap:6px; align-items:center; }
.sum{ display:flex; gap:13px; align-items:center; }
.sum__sh{ width:56px; height:72px; border-radius:8px; background:var(--wash); flex:none; overflow:hidden; }
.sum__sh img{ width:100%; height:100%; object-fit:cover; }
.sum__n{ font-family:var(--f-serif); font-style:italic; font-size:19px; }
.sum__p{ font-size:12.5px; color:var(--t2); }
.sum__price{ margin-inline-start:auto; font-size:20px; font-weight:700; }
.coupon{ display:flex; gap:9px; margin-top:16px; }
.coupon .f__in{ flex:1; }
.brands{ display:flex; gap:8px; align-items:center; margin-bottom:16px; }

/* ---------- confirmation ---------- */
.ref{
  background:var(--wash); border-radius:var(--r-input); padding:15px;
  font-size:15px; letter-spacing:.04em; margin:20px 0 6px; direction:ltr;
}

/* ---------- personal area ---------- */
.tiles{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:16px; }
.tile{
  background:var(--paper); border:1px solid var(--line); border-radius:var(--r-card);
  padding:18px 14px; text-align:center; cursor:pointer;
  display:flex; flex-direction:column; align-items:center; gap:9px;
  font-size:13.5px; color:var(--t1);
}
.tile svg{ color:var(--clay); }
.tile:hover{ border-color:var(--clay); }
.mycard{ display:flex; gap:14px; align-items:flex-start; }
.mycard__sh{ width:66px; height:86px; border-radius:9px; background:var(--wash); flex:none; overflow:hidden; }
.mycard__sh img{ width:100%; height:100%; object-fit:cover; }

/* ============================================================
   Smart filter sheet
   ============================================================ */
.tools__btn{ position:relative; }
.tools__badge{
  min-width:18px; height:18px; border-radius:9px; background:var(--clay);
  color:#fff; font-size:11px; display:inline-flex; align-items:center;
  justify-content:center; padding:0 5px; margin-inline-start:2px;
}
.tools__btn.is-active{ background:var(--clay); }

.sheet-bg{
  position:fixed; inset:0; background:rgba(20,20,20,.42); z-index:190;
  opacity:0; pointer-events:none; transition:opacity .26s var(--ease);
}
.sheet-bg.is-open{ opacity:1; pointer-events:auto; }
.sheet{
  position:fixed; inset-inline:0; bottom:0; z-index:191;
  background:var(--paper); border-radius:20px 20px 0 0;
  max-height:86vh; display:flex; flex-direction:column;
  transform:translateY(101%); transition:transform .30s var(--ease);
  max-width:520px; margin:0 auto;
}
.sheet.is-open{ transform:none; }
.sheet__grip{ width:38px; height:4px; border-radius:2px; background:var(--line-strong); margin:10px auto 4px; }
.sheet__hd{
  display:flex; align-items:center; justify-content:space-between;
  padding:10px 20px 14px; border-bottom:1px solid var(--line-2);
}
.sheet__bd{ padding:18px 20px 8px; overflow-y:auto; flex:1; }
.sheet__ft{
  padding:14px 20px calc(14px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line-2); display:flex; gap:10px; align-items:center;
}
.sheet__ft .btn{ flex:1; }

.fgroup{ margin-bottom:22px; }
.fgroup__t{ font-size:13px; font-weight:600; margin-bottom:11px; }
.fwrap{ display:flex; flex-wrap:wrap; gap:8px; }
.fchip{
  display:inline-flex; align-items:center; gap:6px;
  padding:9px 15px; border-radius:var(--r-pill);
  background:var(--paper); border:1px solid var(--line);
  font-size:13.5px; color:var(--t2); cursor:pointer;
}
.fchip__n{ font-size:11px; color:var(--t3); }
.fchip.is-on{ background:var(--clay-a11y); border-color:var(--clay-a11y); color:#fff; }
.fchip.is-on .fchip__n{ color:rgba(255,255,255,.75); }
.fchip.is-off{ opacity:.38; pointer-events:none; text-decoration:line-through; }

.fbar{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin:0 0 14px; font-size:13px; color:var(--t2);
}
.fbar__clear{ color:var(--clay-txt); cursor:pointer; background:none; border:none; font-size:13px; }
.ftags{ display:flex; flex-wrap:wrap; gap:7px; }
.ftag{
  display:inline-flex; align-items:center; gap:6px;
  background:var(--clay-soft); color:var(--clay-txt);
  border-radius:var(--r-pill); padding:5px 11px; font-size:12px;
}
.ftag button{ background:none; border:none; color:inherit; cursor:pointer; font-size:14px; line-height:1; padding:0; }

/* ============================================================
   Prototype v3 refinements
   ============================================================ */

/* gallery card: view link + choose button, no package label */

/* pagination with prev/next labels */
.pager{ gap:6px; flex-wrap:wrap; }
.pager__nav{
  display:inline-flex; align-items:center; gap:5px;
  min-width:auto; padding:0 13px; border-radius:var(--r-pill);
  font-size:12.5px; color:var(--t2);
}

/* design detail: bordered feature boxes */
.dt__feats{ gap:10px; }
.dt__feat{
  border:1px solid var(--line); border-radius:12px; background:var(--paper);
  padding:14px 6px 12px; gap:8px;
}

/* accordion as a bordered control */
.acc{ background:var(--paper); }
.acc__hd{ font-weight:500; }

/* ---------- payment v3 ---------- */
.f__lab--sm{ font-size:12.5px; font-weight:400; color:var(--t2); margin-bottom:6px; }
/* A line under a field that says what it is for. "כמה הוזמנו" reads as
   a seat number to anyone who has ever booked a table, and it is not
   one — there is no seating in this product. */
.f__hint{ display:block; font-size:11.5px; color:var(--t3); line-height:1.6; margin-top:6px; }
.paybox{
  border:1px solid var(--line); border-radius:14px;
  background:var(--paper); padding:20px 16px; margin-top:12px;
}
.brands{ display:flex; gap:9px; align-items:center; justify-content:center; margin-bottom:20px; }
.brands svg{ border-radius:5px; }

/* summary card with edit affordance */
.sumcard{ border:1px solid var(--line); border-radius:14px; background:var(--paper); padding:16px; position:relative; }
.sumcard__edit{
  position:absolute; top:14px; inset-inline-end:14px;   /* LEFT in RTL, clear of the name */
  width:28px; height:28px; border-radius:8px; border:1px solid var(--line);
  background:var(--wash); display:flex; align-items:center; justify-content:center;
  color:var(--t2); cursor:pointer;
}
/* The gutter belongs to the ROW, not to the text. Reserving it on
   .sumrow__txt kept the words clear of the pencil but not the
   thumbnail, which is the row's other child and sits in exactly the
   same corner — so the edit button landed on top of the artwork. */
.sumrow{ display:flex; gap:12px; align-items:flex-start; padding-inline-end:34px; }
.sumrow__txt{ flex:1; }
.sumrow__lbl{ font-size:11.5px; color:var(--t3); }
.sumrow__val{ font-size:16px; font-weight:600; }
.sumcard__rule{ height:1px; background:var(--line); margin:14px 0; }
.sumcard__total{ display:flex; justify-content:space-between; align-items:baseline; font-size:15px; }
.sumcard__total b{ font-size:17px; }

.coupon{ display:flex; gap:9px; margin-top:14px; }
.coupon .f__in{ flex:1; }
.coupon .btn{ width:auto; padding:0 26px; }

/* the two halves of the payment screen */
.pay__sum{ margin-top:24px; }
.pay__form{ margin-top:22px; }
.pay__form .lead{ margin:0 0 14px; }
.pay__form .btn{ width:100%; margin-top:16px; }
.trust{
  display:flex; align-items:center; justify-content:center; gap:7px;
  font-size:12.5px; color:var(--t3); margin-top:13px;
}
.trust svg{ flex:none; }

/* confirmation confetti */
.done__dots{
  position:absolute; inset:0; z-index:0; opacity:.5;
  background-image:
    radial-gradient(circle, var(--clay) 1.5px, transparent 1.6px),
    radial-gradient(circle, var(--clay) 1px, transparent 1.1px);
  background-size:54px 54px, 33px 33px;
  background-position:0 0, 17px 21px;
  -webkit-mask-image:radial-gradient(ellipse 78% 46% at 50% 26%, #000 0%, transparent 72%);
          mask-image:radial-gradient(ellipse 78% 46% at 50% 26%, #000 0%, transparent 72%);
}
.done__tick--clay{ background:var(--clay) !important; }

/* ============================================================
   Customisation wizard (3 steps) + rich personal area
   ============================================================ */
.step-band{ background:var(--paper); border-bottom:1px solid var(--line-2); padding:16px 18px 6px; }
.step-band .step{ margin:0 0 8px; }
/* Same story as #hd: the steps bar is built by script into an empty
   div, and the form under it jumped down when it arrived. flow-root
   keeps the bar's own bottom margin inside the box, so the height
   held open here is the height it really ends up. Measured at 360,
   390, 768 and 1280 — identical at all four. */
.step-band #steps{ display:flow-root; min-height:61.6px; }

/* section rows on step 2 */
.srow{
  display:flex; align-items:center; gap:13px; width:100%; text-align:start;
  background:var(--paper); border:1px solid var(--line); border-radius:14px;
  padding:14px; margin-bottom:11px; cursor:pointer;
  transition:border-color .2s var(--ease);
}
.srow:hover{ border-color:var(--clay); }
.srow__ic{
  width:52px; height:52px; border-radius:10px; background:var(--wash);
  display:flex; align-items:center; justify-content:center; flex:none;
  color:var(--t3); overflow:hidden;
}
.srow__ic img{ width:100%; height:100%; object-fit:cover; }
.srow__txt{ flex:1; min-width:0; }
.srow__t{ font-size:15px; font-weight:600; }
.srow__s{ font-size:12.5px; color:var(--t2); }
.srow__s--edit{ color:var(--clay-txt); text-decoration:underline; text-underline-offset:2px; }
.srow__ch{ color:var(--t3); flex:none; }
.srow.is-done .srow__ic{ background:var(--clay-soft); color:var(--clay); }

/* step 3 — ready */
.ready__phone{ display:flex; justify-content:center; margin:8px 0 22px; }
.ready__phone .slotbox{
  width:196px; aspect-ratio:9/17; border-radius:18px; background:var(--wash);
  border:1px solid var(--line); display:flex; align-items:center; justify-content:center;
  color:var(--t3); font-size:12px; text-align:center; padding:14px;
}
.linkbox{
  display:flex; align-items:center; gap:10px;
  background:var(--paper); border:1px solid var(--line); border-radius:12px;
  padding:13px 15px; margin-bottom:12px;
}
.linkbox span{ flex:1; font-size:13.5px; direction:ltr; text-align:left;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.linkbox button{ background:none; border:none; color:var(--t2); cursor:pointer; }
.infobox{
  background:var(--wash); border-radius:12px; padding:18px 16px;
  font-size:13.5px; line-height:1.85; color:var(--t2); margin:18px 0;
}

/* ---------- personal area ---------- */
.welcome{ background:var(--paper); border:1px solid var(--line); border-radius:var(--r-card); padding:20px; }
.welcome__hi{ font-size:19px; font-weight:600; color:var(--clay-txt); }
.welcome__names{ font-size:21px; font-weight:700; }
.welcome__rule{ height:1px; background:var(--line); margin:14px 0; }
.welcome__row{ display:flex; gap:14px; align-items:flex-start; }
.welcome__meta{ flex:1; font-size:13.5px; line-height:2; color:var(--t2); }
.welcome__meta b{ color:var(--t1); font-size:15px; font-weight:600; display:block; margin-bottom:2px; }
.welcome__meta i{ font-style:normal; display:inline-flex; align-items:center; gap:6px; }
.welcome__sh{ width:78px; height:100px; border-radius:10px; background:var(--wash); flex:none; overflow:hidden; }
.welcome__sh img{ width:100%; height:100%; object-fit:cover; }
.live-dot::before{ content:''; width:7px; height:7px; border-radius:50%; background:#3DBE5F;
  display:inline-block; margin-inline-end:7px; }

/* The quick actions sit inside the status card. On a phone that is a
   ruled-off strip at the bottom of it; on desktop it becomes the
   card's third column. */
/* ---------- the "carry on" bar ----------
   Reuses the card idiom rather than inventing a banner: it is the
   same object as everything else on this screen, just the one that
   is asking for something. The clay edge is the only thing marking
   it out, and it disappears the moment the invitation is published. */
.resume{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  background:var(--paper); border:1px solid var(--line);
  border-inline-start:3px solid var(--clay);
  border-radius:var(--r-card); padding:18px 20px; margin-top:18px;
  transition:border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.resume:hover{ box-shadow:0 6px 16px rgba(60,45,32,.07); }
.resume[hidden]{ display:none; }
.resume__t{ flex:1; min-width:180px; }
.resume__t b{ display:block; font-size:15.5px; font-weight:600; }
.resume__t span{ font-size:13px; color:var(--t2); }
/* auto width: it is one deliberate act, not a form field */
.resume__b{ width:auto; flex:none; padding-inline:26px; }

.qa{ margin-top:18px; padding-top:15px; border-top:1px solid var(--line-2); }
.qa__t{ font-size:12px; color:var(--t3); text-align:center; margin-bottom:9px; }
.qa__row{ display:flex; gap:9px; }
/* WhatsApp's own green. The other two are app actions and stay clay;
   this one is a jump to another product and is recognised by colour
   long before the label is read.

   Doubled class on purpose: `.qa__btn svg` is declared further down
   with the same specificity, and would otherwise win on order alone. */
.qa__btn.qa__btn--wa svg{ color:#25D366; }

/* ---------- the invitation, in a phone ----------
   Desktop only, and switched on in /admin/. Drawn rather than
   imaged: a mockup PNG would need re-exporting every time the
   palette changes, and this one just follows the tokens. */
/* The dashboard mockup. It holds a real phoneFrame() now — the
   couple's own invitation running in an iframe — so the bezel and
   the notch come from .pframe and there is no second set here. */
.welcome__phone{ display:none; }
.welcome__phone .pframe{ width:186px; margin:0 auto; }
.qa__btn{
  flex:1; min-width:0;
  display:flex; align-items:center; justify-content:center; gap:6px;
  background:var(--paper); border:1px solid var(--line); border-radius:11px;
  padding:11px 4px; font-size:11.5px; color:var(--t1); cursor:pointer;
}
/* Three across inside the status card leaves about 100px per button on
   a 390px phone, and "שיתוף בוואטסאפ" does not fit in that beside its
   icon at any size worth reading. So on a phone they stack: full-width
   rows, label at the reading edge and the icon at the far end — the
   same shape the desktop column uses, and a better tap target than a
   third of a row. They go back to three across from 560px, where the
   width is there. */
.qa__row{ flex-direction:column; gap:8px; }
.qa__btn{
  width:100%; flex:none; border-radius:12px;
  flex-direction:row-reverse; justify-content:space-between;
  padding:13px 15px; font-size:13px; background:var(--bg);
}
@media (min-width:560px){
  .qa__row{ flex-direction:row; gap:9px; }
  .qa__btn{
    flex:1; width:auto; flex-direction:row; justify-content:center;
    padding:11px 6px; font-size:12px; background:var(--paper);
  }
}
.qa__btn svg{ color:var(--clay); flex:none; }
.qa__btn:hover{ border-color:var(--clay); }

/* rsvp summary with donut */
.rsvpcard{ background:var(--paper); border:1px solid var(--line); border-radius:var(--r-card); padding:18px; margin-top:14px; }
.rsvpcard__t{ font-size:13px; color:var(--t2); text-align:center; margin-bottom:14px; }
.rsvpgrid{ display:grid; grid-template-columns:110px 1fr; gap:14px; align-items:center; }
.rsvpnums{ display:grid; grid-template-columns:1fr 1fr; gap:12px 6px; text-align:center; }
/* five figures: the total across the top, the four answers in a 2x2 */
.rsvpnums > :first-child{ grid-column:1 / -1; }
.rsvpnums b{ display:block; font-size:24px; font-weight:700; line-height:1.1; }
.rsvpnums span{ font-size:11.5px; color:var(--t2); }
.rsvpnums .is-yes b{ color:#2E8A4A; }

/* ---------- the head count ----------
   Set apart from the four counters above it because it answers a
   different question: those count invitations, this counts people,
   and it is the number that goes to the caterer. */
.headcount{
  display:flex; align-items:center; justify-content:space-between;
  margin-top:16px; padding-top:14px; border-top:1px solid var(--line-2);
}
.headcount__l{ font-size:13px; color:var(--t2); }
.headcount__v{ font-size:22px; font-weight:700; font-variant-numeric:tabular-nums; }

/* the countdown beside the live dot */
.cdown{
  display:inline-block; margin-inline-start:10px; padding:2px 10px;
  border-radius:var(--r-pill); background:var(--clay-soft);
  color:var(--clay-txt); font-size:12px; font-weight:600;
}

/* activity */
.actcard{ background:var(--paper); border:1px solid var(--line); border-radius:var(--r-card); padding:16px 18px; margin-top:14px; }
.actrow{ display:flex; align-items:center; gap:11px; padding:11px 0; border-bottom:1px solid var(--line-2); }
.actrow:last-of-type{ border-bottom:none; }
.actrow__ic{ width:26px; height:26px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center; }
.actrow__ic--yes{ background:#E8F6EC; color:#3DBE5F; }
.actrow__ic--wait{ background:var(--wash); color:var(--t3); }
/* a decline is an answer, not a silence — it gets its own mark */
.actrow__ic--no{ background:#FBEAE7; color:#C0503A; }
.actrow__ic--maybe{ background:#EEF1F7; color:#5A6A8C; }
.actrow__txt{ flex:1; }
.actrow__n{ font-size:14px; }
.actrow__s{ font-size:11.5px; color:var(--t3); }
.actrow time{ font-size:11.5px; color:var(--t3); white-space:nowrap; }

.helpbox{ background:var(--wash); border-radius:var(--r-card); padding:22px 18px; text-align:center; margin-top:18px; }

/* ---------- the dark support block ----------
   The mockup's version, and the default. /admin/ can switch it back
   to the quiet wash above with עיצוב האתר → האזור האישי → בלוק העזרה.
   The botanical line-work is drawn as an inline SVG so it costs no
   request and inherits nothing that can break. */
html[data-home-help="dark"] .helpbox{
  background:var(--ink); color:var(--on-dark);
  position:relative; overflow:hidden; padding:30px 22px;
}
html[data-home-help="dark"] .helpbox .h3{ color:#fff; }
html[data-home-help="dark"] .helpbox .muted{ color:var(--on-dark-2); }
/* one sprig, mirrored to the other end. `scale(-1,1)` on the second
   copy rather than a second drawing. */
html[data-home-help="dark"] .helpbox::before,
html[data-home-help="dark"] .helpbox::after{
  content:''; position:absolute; top:50%; width:150px; height:150px;
  transform:translateY(-50%); opacity:.14; pointer-events:none;
  background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 120' fill='none' stroke='%23ffffff' stroke-width='1.1' stroke-linecap='round'%3E%3Cpath d='M60 112C60 70 46 40 18 20'/%3E%3Cpath d='M44 84c-10-2-18-9-21-19 11-1 20 5 24 15'/%3E%3Cpath d='M52 96c9-4 14-13 14-24-10 3-16 11-17 21'/%3E%3Cpath d='M34 62c-11-3-18-11-20-22 11 0 20 7 23 17'/%3E%3Cpath d='M42 72c8-5 12-14 11-25-9 4-14 13-14 23'/%3E%3Cpath d='M24 40c-10-4-15-13-16-24 11 1 19 9 21 19'/%3E%3C/svg%3E");
}
html[data-home-help="dark"] .helpbox::before{ right:-26px; }   /* physical: one at each end */
html[data-home-help="dark"] .helpbox::after{ left:-26px; transform:translateY(-50%) scale(-1,1); }
/* the button must sit above the line-work */
html[data-home-help="dark"] .helpbox .h3,
html[data-home-help="dark"] .helpbox p,
html[data-home-help="dark"] .helpbox .btn{ position:relative; z-index:1; }

/* ============================================================
   Gentle motion
   Quiet by design: things settle into place, nothing bounces.
   ============================================================ */

/* The donut is animated in JS: CSS transitions do not fire reliably
   on SVG presentation attributes, so it snapped instead of drawing. */
.donut__track{ opacity:0; animation: donutTrack .7s var(--ease) forwards; }
@keyframes donutTrack{ to{ opacity:1; } }
.donut{ opacity:0; transform:scale(.94); animation: donutIn .8s var(--ease) .05s forwards; }
@keyframes donutIn{ to{ opacity:1; transform:none; } }

/* numbers tick up rather than snapping */
.rsvpnums b{ font-variant-numeric: tabular-nums; }

/* sections settle in on first view */
.rise{ opacity:0; transform:translateY(14px);
  transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rise.is-in{ opacity:1; transform:none; }

/* quick-action and tile presses feel physical */
.qa__btn, .tile, .srow{ transition:border-color .2s var(--ease), transform .16s var(--ease),
                                   box-shadow .2s var(--ease); }
.qa__btn:active, .tile:active, .srow:active{ transform:scale(.978); }
.tile:hover{ box-shadow:0 6px 16px rgba(60,45,32,.07); }

/* a new answer arriving gives the row one soft pulse */
@keyframes rowIn{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:none; } }
.actrow--new{ animation: rowIn .55s var(--ease); }

@media (prefers-reduced-motion:reduce){
  .donut, .donut__track, .actrow--new{ animation:none; opacity:1; transform:none; }
  .donut__seg{ transition:none; }
  .rise{ opacity:1; transform:none; transition:none; }
}


/* ============================================================
   Hebrew date picker
   Native <input type=date> follows the OS locale, so its popup
   cannot be forced into Hebrew. This is a small custom one.
   ============================================================ */
.dp{ position:relative; }
.dp__field{
  width:100%; padding:16px 17px; background:var(--paper);
  border:1px solid var(--line); border-radius:var(--r-input);
  font-size:16px; color:var(--t1); cursor:pointer; text-align:start;
  display:flex; align-items:center; justify-content:space-between; gap:10px;
}
.dp__field:focus{ outline:none; border-color:var(--clay); box-shadow:0 0 0 3px rgba(193,112,91,.10); }
.dp__val{ direction:ltr; letter-spacing:.06em; font-variant-numeric:tabular-nums; }
.dp__val--empty{ color:var(--t3); }
.dp__field svg{ color:var(--clay); flex:none; }

.dp__pop{
  position:absolute; z-index:120; inset-inline:0; top:calc(100% + 8px);
  background:var(--paper); border:1px solid var(--line); border-radius:14px;
  box-shadow:0 16px 40px rgba(60,45,32,.16); padding:14px;
  opacity:0; transform:translateY(-6px); pointer-events:none;
  transition:opacity .2s var(--ease), transform .2s var(--ease);
}
/* On a phone the calendar opened downward from a field already near
   the bottom, so the last week and the היום / ניקוי buttons were off
   the screen with no way to reach them. Below 560px it becomes a
   sheet: anchored to the bottom, never taller than the screen, and
   scrollable if it still does not fit. */
@media (max-width:559px){
  .dp__pop{
    position:fixed; inset-inline:12px; top:auto;
    bottom:calc(12px + env(safe-area-inset-bottom));
    max-height:min(78vh, 560px); overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    transform:translateY(8px); padding:16px;
  }
  .dp__day{ font-size:15px; }
  .dp__nav{ width:38px; height:38px; }
  .dp__title select{ font-size:16px; padding:6px 4px; }
}
/* the dimmer behind that sheet */
.dp__veil{
  position:fixed; inset:0; z-index:119; background:rgba(20,20,20,.34);
  opacity:0; pointer-events:none; transition:opacity .2s var(--ease);
}
.dp__veil.is-open{ opacity:1; pointer-events:auto; }
@media (min-width:560px){ .dp__veil{ display:none; } }
.dp__pop.is-open{ opacity:1; transform:none; pointer-events:auto; }
.dp__hd{ display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.dp__nav{
  width:30px; height:30px; border-radius:50%; border:1px solid var(--line);
  background:var(--paper); cursor:pointer; color:var(--t2);
  display:flex; align-items:center; justify-content:center;
}
.dp__nav:hover{ border-color:var(--clay); color:var(--clay-txt); }
.dp__title{ font-size:14.5px; font-weight:600; }
.dp__title select{
  border:none; background:none; font:inherit; color:inherit; cursor:pointer; padding:2px;
}
.dp__grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
.dp__dow{ font-size:11px; color:var(--t3); text-align:center; padding:5px 0; }
.dp__day{
  aspect-ratio:1; border:none; background:none; cursor:pointer;
  border-radius:9px; font-size:13.5px; color:var(--t1);
  display:flex; align-items:center; justify-content:center;
}
.dp__day:hover{ background:var(--wash); }
.dp__day.is-out{ color:var(--t3); opacity:.45; }
.dp__day.is-today{ box-shadow:inset 0 0 0 1px var(--line-strong); }
.dp__day.is-on{ background:var(--clay); color:#fff; font-weight:600; }
.dp__day[disabled]{ opacity:.25; pointer-events:none; }
.dp__foot{ display:flex; justify-content:space-between; margin-top:10px; padding-top:10px;
  border-top:1px solid var(--line-2); }
.dp__foot button{ background:none; border:none; cursor:pointer; font-size:13px; color:var(--clay-txt); }

/* ============================================================
   Admin (Nikol only)
   ============================================================ */
.adm{ max-width:760px; margin:0 auto; padding:22px 18px 80px; }
.adm__tabs{ display:flex; gap:7px; overflow-x:auto; margin-bottom:20px; scrollbar-width:none; }
.adm__tabs::-webkit-scrollbar{ display:none; }
.adm__tab{
  flex:none; padding:9px 17px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:var(--paper);
  font-size:13.5px; color:var(--t2); cursor:pointer; white-space:nowrap;
}
.adm__tab.is-on{ background:var(--ink); border-color:var(--ink); color:#fff; }

.adm-card{
  background:var(--paper); border:1px solid var(--line);
  border-radius:14px; padding:16px; margin-bottom:13px;
}
.adm-card__hd{ display:flex; align-items:center; gap:12px; }
.adm-card__sh{
  width:52px; height:66px; border-radius:8px; background:var(--wash);
  flex:none; overflow:hidden; position:relative; cursor:pointer;
}
.adm-card__sh img{ width:100%; height:100%; object-fit:cover; }
.adm-card__sh:hover::after{
  content:'החלפה'; position:absolute; inset:0; background:rgba(20,20,20,.62);
  color:#fff; font-size:10px; display:flex; align-items:center; justify-content:center;
}
.adm-card__t{ flex:1; min-width:0; }
.adm-card__name{ font-family:var(--f-serif); font-style:italic; font-size:19px; }
.adm-card__meta{ font-size:11.5px; color:var(--t3); }
.adm-card__body{ display:none; margin-top:14px; padding-top:14px; border-top:1px solid var(--line-2); }
.adm-card.is-open .adm-card__body{ display:block; }
.adm-card.is-open .adm-card__ch{ transform:rotate(180deg); }
.adm-card__ch{ color:var(--t3); transition:transform .22s var(--ease); }

.adm-lab{ display:block; font-size:12px; color:var(--t2); margin:12px 0 5px; font-weight:500; }
.adm-in, .adm-ta{
  width:100%; padding:11px 13px; border:1px solid var(--line);
  border-radius:9px; font-size:14.5px; background:var(--bg); color:var(--t1);
}
.adm-ta{ min-height:88px; resize:vertical; line-height:1.7; }
.adm-in:focus,.adm-ta:focus{ outline:none; border-color:var(--clay); background:var(--paper); }
.adm-row{ display:grid; grid-template-columns:1fr 1fr; gap:11px; }

.adm-toggles{ display:flex; flex-wrap:wrap; gap:7px; margin-top:6px; }
.adm-tg{
  padding:7px 13px; border-radius:var(--r-pill); border:1px solid var(--line);
  background:var(--paper); font-size:12.5px; color:var(--t2); cursor:pointer;
}
.adm-tg.is-on{ background:var(--clay); border-color:var(--clay); color:#fff; }

.adm-feats{ margin-top:6px; }
.adm-feat{ display:flex; gap:8px; align-items:center; margin-bottom:7px; }
.adm-feat .adm-in{ flex:1; }
.adm-feat button{ background:none; border:none; color:var(--t3); cursor:pointer; font-size:16px; padding:0 6px; }

.adm-save{
  position:sticky; bottom:0; background:linear-gradient(transparent, var(--bg) 30%);
  padding:16px 0 8px; margin-top:6px;
}
.adm-note{ font-size:12px; color:var(--t3); margin-top:8px; text-align:center; }
.adm-gate{ max-width:400px; margin:70px auto; text-align:center; padding:0 20px; }

/* ============================================================
   ADMIN · פניות

   A worklist. Colour carries the status so the list can be read
   without reading it — an unanswered enquiry should be visible from
   across the room, and a closed one should stop asking for
   attention.
   ============================================================ */
.adm__tab__n{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:17px; height:17px; padding:0 5px; margin-inline-start:6px;
  border-radius:9px; background:var(--clay); color:#fff; font-size:11px;
}
.adm__tab.is-on .adm__tab__n{ background:#fff; color:var(--ink); }

/* the unanswered ones carry a clay edge; everything else is quiet */
.lead{ border-inline-start:3px solid transparent; }
.lead--new{ border-inline-start-color:var(--clay); }
.lead--talking{ border-inline-start-color:#D9A441; }
.lead--won, .lead--lost{ opacity:.72; }

.lead__st{
  flex:none; padding:4px 11px; border-radius:var(--r-pill);
  font-size:11.5px; white-space:nowrap;
}
.lead__st--new{     background:var(--clay-soft); color:var(--clay-txt); }
.lead__st--talking{ background:#FAF3E6; color:#9A7A31; }
.lead__st--won{     background:#E9F6EC; color:#2E9E4F; }
.lead__st--lost{    background:var(--wash);  color:var(--t3); }

.lead__note{
  background:var(--wash); border-radius:var(--r-input);
  padding:13px 15px; margin:0 0 14px;
  font-size:13.5px; line-height:1.75; color:var(--t2); white-space:pre-wrap;
}
/* Call, WhatsApp, mail. Auto width — these are three small acts, and
   a button stretched across the card would read as a form field. */
.lead__acts{ display:flex; flex-wrap:wrap; gap:8px; }
.lead__acts .btn{ width:auto; gap:7px; }

/* ============================================================
   ADMIN · עיצוב האתר

   Controls on one side, the real site in an iframe on the other.
   On a phone the preview goes below the controls rather than beside
   them — a 390px column split in two would make both halves
   useless, the same reasoning as the invitation editor.
   ============================================================ */
.sd{ display:block; }
.sd__panes{ display:flex; flex-wrap:wrap; gap:7px; }

.sd__color{ display:flex; gap:9px; align-items:center; }
.sd__color input[type="color"]{
  width:46px; height:40px; padding:0; flex:none; cursor:pointer;
  border:1px solid var(--line); border-radius:9px; background:var(--paper);
}
.sd__color .adm-in{ flex:1; text-transform:uppercase; }

.sd__num{ display:flex; align-items:center; gap:12px; }
.sd__num input[type="range"]{ flex:1; accent-color:var(--clay); }
.sd__num output{
  flex:none; min-width:56px; text-align:center; font-size:13px;
  color:var(--t2); font-variant-numeric:tabular-nums;
}

.sd__img{ display:flex; gap:12px; align-items:flex-start; }
.sd__imgsh{
  width:96px; height:64px; border-radius:9px; overflow:hidden; flex:none;
  background:var(--wash); border:1px solid var(--line); cursor:pointer;
}
.sd__imgsh img{ width:100%; height:100%; object-fit:cover; }

.sd__save{
  position:sticky; bottom:0; z-index:2;
  background:linear-gradient(transparent, var(--bg) 32%);
  padding:18px 0 10px; margin-top:10px;
}
.sd__saverow{
  display:flex; justify-content:space-between; gap:12px;
  margin-top:11px; font-size:13px;
}

/* ---- the preview ---- */
.sd__pv{ margin-top:22px; }
.sd__pvhd{
  display:flex; align-items:center; gap:10px; margin-bottom:12px; flex-wrap:wrap;
}
.sd__pvsel{ flex:1; min-width:150px; }
.sd__pvdev{ display:flex; gap:6px; flex:none; }
/* The frame renders at a true device width and is scaled down, so
   what you judge is the real layout rather than a reflowed one. Hence
   the fixed size on the iframe and the transform on top of it. */
.sd__stage{
  position:relative; overflow:hidden;
  border:1px solid var(--line); border-radius:14px; background:var(--wash);
}
.sd__stage iframe{
  position:absolute; top:0; left:0;      /* PHYSICAL: transform-origin must
                                            not flip with the page's RTL */
  border:0; display:block; transform-origin:top left; background:#fff;
}

@media (min-width:1000px){
  /* Only this tab gets the extra width — the catalogue tabs are lists
     of cards and read better in the narrower column they were built
     for, so the widening is scoped to the tab that needs it. */
  .adm:has(.sd){ max-width:1280px; }
  .sd{
    display:grid; grid-template-columns:minmax(340px, 420px) 1fr;
    gap:28px; align-items:start;
  }
  .sd__pv{
    margin-top:0; position:sticky; top:calc(var(--header-h) + 18px);
  }
}

/* ============================================================
   Guests · Send · Settings · RSVP
   ============================================================ */
.search{ position:relative; margin-bottom:14px; }
.search input{ width:100%; padding:14px 44px 14px 16px; border:1px solid var(--line);
  border-radius:var(--r-input); background:var(--paper); font-size:14.5px; }
.search input:focus{ outline:none; border-color:var(--clay); }
.search svg{ position:absolute; inset-inline-end:15px; top:50%; transform:translateY(-50%); color:var(--t3); }

.fchips{ display:flex; gap:8px; overflow-x:auto; padding-bottom:4px; margin-bottom:14px; scrollbar-width:none; }
.fchips::-webkit-scrollbar{ display:none; }
.fchip2{ flex:none; display:inline-flex; align-items:center; gap:6px; padding:8px 15px;
  border-radius:var(--r-pill); border:1px solid var(--line); background:var(--paper);
  font-size:13px; color:var(--t2); cursor:pointer; white-space:nowrap; }
.fchip2.is-on{ background:var(--clay); border-color:var(--clay); color:#fff; }
.fchip2 svg{ width:14px; height:14px; }
/* the count on a group chip: quieter than the name, and it has to stay
   legible once the chip turns clay */
.fchip2__n{ font-weight:600; font-size:11.5px; opacity:.62; margin-inline-start:2px; }
.fchip2.is-on .fchip2__n{ opacity:.85; }
/* what the chosen group adds up to */
.gsum{ font-size:12.5px; color:var(--t2); line-height:1.75; margin:-4px 0 14px; }
.gsum b{ color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums; }

.gbtns{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:18px; }

.gtable{ background:var(--paper); border:1px solid var(--line); border-radius:14px; overflow:hidden; }
.ghead{ display:grid; grid-template-columns:1.6fr .9fr .7fr 1fr; gap:8px;
  padding:11px 14px; background:var(--bg); border-bottom:1px solid var(--line);
  font-size:11px; color:var(--t3); }
/* Each row is a <button>, and nothing here ever reset it — so every
   guest was drawn with the browser's native button chrome: the grey
   buttonface fill and the dark default border, on both phone and
   desktop. The row is a row; it only happens to be a button so it can
   be tapped and focused. Hence the full reset.

   `font:inherit` matters as much as the colours: without it the names
   fall back to the UA's button font rather than the app's Hebrew face. */
.grow{ display:grid; grid-template-columns:1.6fr .9fr .7fr 1fr; gap:8px; align-items:center;
  padding:13px 14px; border:none; border-bottom:1px solid var(--line-2);
  background:var(--paper); color:inherit; font:inherit; text-align:start;
  width:100%; cursor:pointer; transition:background .15s var(--ease); }
.grow:last-child{ border-bottom:none; }
.grow:hover{ background:var(--bg); }
/* a visible ring for keyboard users, which the native border was
   accidentally providing before */
.grow:focus-visible{ outline:2px solid var(--clay); outline-offset:-2px; }
.gname{ display:flex; align-items:center; min-width:0; }
.gname__t{ min-width:0; }
.gname__n{ font-size:14px; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* a phone number is one token — breaking it after the prefix reads as
   two different numbers stacked */
.gname__p{ font-size:11.5px; color:var(--t3); direction:ltr; text-align:start;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* A grid item stretches to its track by default, so the pill grew to
   whatever the status column happened to be — a 200px lozenge around
   the word "ממתינים" on a wide screen. A badge should be the size of
   its own text at every width. */
.gbadge{ display:inline-flex; align-items:center; gap:5px; padding:5px 9px; border-radius:var(--r-pill);
  font-size:11.5px; white-space:nowrap; justify-self:center; }
.gbadge--yes{ background:#E9F6EC; color:#2E9E4F; }
.gbadge--no{ background:#FBEAE7; color:#C0503A; }
.gbadge--wait{ background:#FAF3E6; color:#9A7A31; }
/* answered "not sure yet" — a cool tone, so it never reads as a yes or a no */
.gbadge--maybe{ background:#EEF1F7; color:#5A6A8C; }
.gbadge svg{ width:13px; height:13px; }
/* ---- where the guest came from, and what we've done about them ----
   Under the name rather than in a column of their own: the row is
   already four tracks wide on a phone, and these read as facts about
   the person, not as a separate field. */
.gmeta{ display:flex; flex-wrap:wrap; gap:5px; margin-top:5px; }
.gchip{
  font-size:10.5px; line-height:1.5; padding:1px 7px; border-radius:var(--r-pill);
  white-space:nowrap; border:1px solid transparent;
}
.src--manual{ background:var(--wash);      color:var(--t2); border-color:var(--line); }
.src--import{ background:var(--wash);      color:var(--t2); border-color:var(--line); }
/* the one origin the couple did not cause: worth its own colour */
.src--rsvp{   background:var(--clay-soft); color:var(--clay-txt); }
.gchip--sent{   background:#E9F6EC; color:#2E9E4F; }
.gchip--unsent{ background:none; color:var(--t3); border-color:var(--line); }
.gchip--dup{    background:#FAF3E6; color:#9A7A31; font-weight:600; }

.gcount{ display:inline-flex; align-items:center; gap:5px; font-size:13px; color:var(--t2); }
.gnote{ font-size:12px; color:var(--t2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* send & reminders */
.linkrow{ display:flex; gap:9px; margin-bottom:12px; }
.linkrow input{ flex:1; padding:13px 14px; border:1px solid var(--line); border-radius:var(--r-input);
  background:var(--paper); font-size:13px; direction:ltr; text-align:start; }
.share4{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px; }
.share4 button{ display:flex; flex-direction:column; align-items:center; gap:7px;
  background:var(--paper); border:1px solid var(--line); border-radius:12px;
  padding:14px 6px; font-size:11.5px; color:var(--t1); cursor:pointer; }
.share4 svg{ color:var(--clay); }
.share4 button:hover{ border-color:var(--clay); }

.seg2{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
.seg2 button{ flex:1; min-width:96px; padding:11px 8px; border-radius:10px; border:1px solid var(--line);
  background:var(--paper); font-size:12.5px; color:var(--t2); cursor:pointer; }
.seg2 button.is-on{ background:var(--clay); border-color:var(--clay); color:#fff; }

.hist{ margin-top:6px; }
.histrow{ display:flex; align-items:center; gap:10px; padding:11px 0; border-bottom:1px solid var(--line-2); }
.histrow:last-child{ border-bottom:none; }
.histrow__ic{ width:22px; height:22px; border-radius:50%; background:#E9F6EC; color:#2E9E4F;
  display:flex; align-items:center; justify-content:center; flex:none; }
.histrow__t{ flex:1; font-size:13px; }
.histrow time{ font-size:11.5px; color:var(--t3); white-space:nowrap; }

/* settings */
.setrow{ display:flex; align-items:center; gap:12px; padding:15px 0; border-bottom:1px solid var(--line-2); }
.setrow:last-child{ border-bottom:none; }
.setrow__ic{ width:34px; height:34px; border-radius:9px; background:var(--wash); color:var(--clay);
  display:flex; align-items:center; justify-content:center; flex:none; }
.setrow__t{ flex:1; min-width:0; }
.setrow__l{ font-size:14px; font-weight:500; }
.setrow__v{ font-size:12.5px; color:var(--t2); }
.sw{ width:44px; height:25px; border-radius:99px; background:var(--line-strong); border:none;
  position:relative; cursor:pointer; flex:none; transition:background .22s var(--ease); }
/* PHYSICAL right/left on purpose. `inset-inline-end` is the LEFT edge on
   an RTL page, so the knob started on the left and then slid a further
   19px left — clean off the track. In Hebrew "off" reads right and "on"
   reads left, and this app is only ever RTL. */
.sw::after{ content:''; position:absolute; top:3px; right:3px; width:19px; height:19px;
  border-radius:50%; background:#fff; transition:transform .22s var(--ease);
  box-shadow:0 1px 2px rgba(20,20,20,.18); }
.sw.is-on{ background:var(--clay); }
.sw.is-on::after{ transform:translateX(-19px); }

/* rsvp analytics */
.donutbig{ display:flex; align-items:center; gap:18px; }
.donutbig__legend{ flex:1; display:flex; flex-direction:column; gap:11px; }
.leg{ display:flex; align-items:center; gap:9px; font-size:13.5px; }
.leg__dot{ width:9px; height:9px; border-radius:50%; flex:none; }
.leg__n{ margin-inline-start:auto; font-weight:600; }
.leg__p{ font-size:11.5px; color:var(--t3); width:34px; text-align:start; }
.bignum{ text-align:center; padding:20px 0; }
.bignum__v{ font-size:38px; font-weight:700; line-height:1; }
.bignum__l{ font-size:12.5px; color:var(--t2); margin-top:6px; }
.bignum__ic{ width:38px; height:38px; border-radius:50%; background:var(--clay-soft); color:var(--clay);
  display:flex; align-items:center; justify-content:center; margin:0 auto 12px; }

/* ============================================================
   THE EDITOR  (setup/editor.html)
   Mobile-first: edit and preview are two tabs, never side by
   side on a phone — a 393px column split in two leaves neither
   half usable. From 900px up they sit next to each other and
   the tabs disappear.
   ============================================================ */
/* The footer is position:fixed, so it sits OUTSIDE the flow and can
   cover whatever the page ends on. Reserving its height here — on the
   scrolling content itself — is what guarantees the last control can
   always be scrolled clear of it. Doing it with padding-bottom on the
   panes instead only worked while the pane happened to be the taller
   grid column; when the sticky preview drove the row height the page
   stopped short and the last button sat under "השלב הבא" unreachably,
   with no scroll left to free it. */
.ed{
  display:flex; flex-direction:column; min-height:100dvh;
  padding-bottom:calc(96px + env(safe-area-inset-bottom));
}

/* --- top strip: which section, and whether it is saved --- */
.ed__bar{
  position:sticky; top:var(--header-h); z-index:40;
  background:var(--paper); border-bottom:1px solid var(--line-2);
  padding:12px 18px 0;
}
.ed__barrow{ display:flex; align-items:center; gap:10px; }
.ed__title{ font-size:16px; font-weight:600; flex:1; min-width:0; }
.ed__save{
  display:inline-flex; align-items:center; gap:6px; flex:none;
  font-size:12px; color:var(--t2); min-height:20px;
  transition:opacity .2s var(--ease);
}
.ed__save svg{ flex:none; }
.ed__save--ok{ color:var(--ok); }
.ed__save--err{ color:#C0392B; }
.ed__dot{
  width:7px; height:7px; border-radius:50%; background:var(--clay);
  animation:edpulse 1.1s var(--ease) infinite;
}
@keyframes edpulse{ 0%,100%{opacity:.25} 50%{opacity:1} }

/* section chips — horizontal scroller, same idiom as .chips */
.ed__steps{
  display:flex; gap:8px; overflow-x:auto; padding:12px 0 12px;
  scrollbar-width:none; -webkit-overflow-scrolling:touch;
}
.ed__steps::-webkit-scrollbar{ display:none; }
.ed__step{
  flex:none; padding:8px 14px; border-radius:var(--r-pill); cursor:pointer;
  border:1px solid var(--line); background:var(--paper);
  font-size:13px; color:var(--t2); white-space:nowrap;
}
.ed__step.is-on{ background:var(--clay); border-color:var(--clay); color:#fff; }

/* the "see it in another design" trigger, in the editor's top strip */
.ed__swap{
  flex:none; padding:6px 13px; cursor:pointer; font-size:12.5px;
  border:1px solid var(--line-strong); border-radius:var(--r-pill);
  background:var(--paper); color:var(--t1); white-space:nowrap;
  transition:background .2s var(--ease), border-color .2s var(--ease);
}
.ed__swap:hover{ background:var(--wash); border-color:var(--clay); }

/* ---- the same invitation, in every design ---- */
.dsg{
  position:fixed; inset:0; z-index:195; background:var(--wash);
  display:flex; flex-direction:column;
}
.dsg[hidden]{ display:none !important; }
.dsg__hd{
  flex:none; display:flex; align-items:flex-start; gap:14px;
  padding:calc(14px + env(safe-area-inset-top)) 18px 14px;
  background:var(--paper); border-bottom:1px solid var(--line-2);
}
.dsg__ttl{ flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.dsg__ttl b{ font-size:15.5px; }
.dsg__ttl span{ font-size:12.5px; color:var(--t2); line-height:1.6; }
.dsg__x{
  flex:none; background:none; border:none; font-size:28px; line-height:1;
  cursor:pointer; color:var(--t2); padding:0 4px;
}
.dsg__bd{
  flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch;
  padding:18px 18px calc(24px + env(safe-area-inset-bottom));
  display:grid; gap:18px; align-content:start;
  grid-template-columns:repeat(auto-fill, minmax(160px, 1fr));
}
.dsg__card{
  background:var(--paper); border:1px solid var(--line);
  border-radius:16px; overflow:hidden; display:flex; flex-direction:column;
}
.dsg__card.is-now{ border-color:var(--clay); box-shadow:0 0 0 1px var(--clay); }
.dsg__vp{
  position:relative; overflow:hidden; background:var(--wash);
  border-bottom:1px solid var(--line-2);
}
/* PHYSICAL top/left: in flow on an RTL page the iframe starts at the
   right edge, so scaling from `top left` would push the invitation
   out of the card. Same reasoning as .pframe__f. */
.dsg__f{
  position:absolute; top:0; left:0; border:0; display:block;
  transform-origin:top left;
}
.dsg__load{
  position:absolute; inset:0; display:grid; place-items:center;
  font-size:12px; color:var(--t2); text-align:center; padding:14px;
}
.dsg__meta{
  flex:none; display:flex; align-items:center; justify-content:space-between;
  gap:10px; padding:11px 13px;
}
.dsg__nm{ font-size:13.5px; font-weight:600; min-width:0; }
.dsg__meta .btn{ flex:none; width:auto; margin:0; }
.dsg__badge{
  flex:none; font-size:11.5px; color:var(--clay-txt);
  background:var(--clay-soft); border-radius:var(--r-pill); padding:4px 10px;
}
@media (min-width:768px){
  .dsg__bd{ grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:24px; padding:26px; }
}

/* --- the two tabs (phones only) --- */
/* STICKY, because it was easy to lose.

   עריכה / תצוגה מקדימה is the only way to see the invitation on a
   phone, and it sat at the top of a long scrolling form — three
   screens up by the time anybody had typed anything. People edited
   blind and never found it. It now rides under the header, so the
   preview is one tap away from wherever they are. */
.ed__tabs{
  display:flex; gap:4px; padding:4px; margin:14px 18px 0;
  background:var(--wash); border-radius:var(--r-pill);
  position:sticky; top:calc(var(--header-h) + 8px); z-index:40;
  box-shadow:0 6px 18px -10px rgba(20,20,20,.35);
}
.ed__tab{
  flex:1; padding:9px 0; border:none; background:none; cursor:pointer;
  border-radius:var(--r-pill); font-size:13.5px; color:var(--t2);
  transition:background .2s var(--ease), color .2s var(--ease);
}
.ed__tab.is-on{ background:var(--paper); color:var(--t1); font-weight:600; }

/* --- body --- */
.ed__body{ flex:1; display:block; }
.ed__pane{ padding:18px 18px 24px; max-width:560px; margin:0 auto; }
/* `display:block` on the pane and `display:flex` on the phone both
   outrank the [hidden] attribute's UA style, so say it explicitly. */
.ed__pane[hidden], .ed__phone[hidden]{ display:none !important; }

/* A COLUMN. It was a row, and it held two children: the screen
   switcher and the phone frame. Side by side, as flex items that
   stretch by default, the two switcher buttons became full-height
   vertical bars with their Hebrew running down the side, and the
   preview was squeezed into what was left. The switcher's own
   margin-bottom was always the giveaway that it belonged above. */
.ed__phone{ padding:18px 18px 24px; display:flex; flex-direction:column;
            align-items:center; }
.ed__frame{
  width:100%; max-width:340px; flex:none; aspect-ratio:9/18.5;
  border-radius:26px; overflow:hidden; background:var(--wash);
  border:1px solid var(--line); box-shadow:0 12px 34px rgba(20,20,20,.10);
}
.ed__frame iframe{ width:100%; height:100%; border:0; display:block; }

/* --- field groups --- */
.ed__grp{ margin-bottom:26px; }
.ed__grp__t{ font-size:13px; font-weight:600; margin:0 0 4px; }
.ed__hint{ font-size:12.5px; color:var(--t2); margin:0 0 12px; line-height:1.7; }
.ed__row{ display:flex; align-items:center; gap:12px; }

textarea.f__in{ min-height:96px; resize:vertical; line-height:1.7; padding-top:12px; }

/* segmented choice, e.g. how the names are written */
.ed__seg{ display:flex; gap:8px; flex-wrap:wrap; }
.ed__segbtn{
  flex:1; min-width:96px; padding:11px 10px; cursor:pointer; text-align:center;
  border:1px solid var(--line); border-radius:var(--r-input);
  background:var(--paper); font-size:14px; color:var(--t2);
}
.ed__segbtn.is-on{ border-color:var(--clay); background:var(--clay-soft); color:var(--clay-txt); font-weight:600; }
.ed__segbtn small{ display:block; font-size:11.5px; color:var(--t3); margin-top:2px; }
.ed__segbtn.is-on small{ color:var(--clay-txt); opacity:.8; }

/* a labelled toggle line */
.ed__tog{
  display:flex; align-items:center; gap:12px; padding:13px 0;
  border-bottom:1px solid var(--line-2);
}
.ed__tog:last-child{ border-bottom:none; }
.ed__tog__t{ flex:1; min-width:0; }
.ed__tog__l{ display:block; font-size:14px; font-weight:500; }
.ed__tog__s{ display:block; font-size:12.5px; color:var(--t2); line-height:1.5; }

/* --- schedule rows --- */
.ed__item{
  display:flex; align-items:center; gap:8px; margin-bottom:9px;
  background:var(--paper); border:1px solid var(--line);
  border-radius:12px; padding:8px 10px;
}
.ed__item .f__in{ margin:0; padding:11px 12px; font-size:14px; }
.ed__item__t{ width:104px; flex:none; padding-inline:8px !important; }
.ed__item__l{ flex:1; min-width:0; }
.ed__ib{
  width:30px; height:30px; flex:none; border-radius:8px; cursor:pointer;
  border:1px solid var(--line); background:var(--paper); color:var(--t2);
  display:flex; align-items:center; justify-content:center; padding:0;
}
.ed__ib:disabled{ opacity:.3; cursor:default; }
.ed__ib--danger{ color:#C0392B; }
.ed__moves{ display:flex; flex-direction:column; gap:3px; flex:none; }
.ed__moves .ed__ib{ height:16px; border:none; background:none; }

/* --- cover image --- */
/* width/height come from coverBox() in editor.html, which caps the
   height so a phone-shaped cover cannot push the next slot off screen.
   max-width keeps it inside a narrow column whatever it computed. */
.ed__cover{
  width:100%; aspect-ratio:4/5; max-width:min(280px, 100%); margin:0 auto 14px;
  border-radius:14px; overflow:hidden; background:var(--wash);
  border:1px dashed var(--line-strong);
  display:flex; align-items:center; justify-content:center;
  color:var(--t3); text-align:center; font-size:13px; padding:20px;
}
.ed__cover img{ width:100%; height:100%; object-fit:cover; }
.ed__cover--set{ border-style:solid; border-color:var(--line); }
.ed__covacts{ display:flex; gap:8px; max-width:280px; margin:0 auto; }
.ed__covacts .btn{ flex:1; }

/* --- the cropper --- */
.crop{
  position:fixed; inset:0; z-index:200; background:rgba(20,20,20,.92);
  display:flex; flex-direction:column; opacity:0; pointer-events:none;
  transition:opacity .24s var(--ease);
}
.crop.is-open{ opacity:1; pointer-events:auto; }
.crop__hd{
  padding:calc(14px + env(safe-area-inset-top)) 18px 12px;
  color:#fff; display:flex; align-items:center; justify-content:space-between;
  font-size:15px; font-weight:600;
}
.crop__x{ background:none; border:none; color:#fff; font-size:26px; line-height:1; cursor:pointer; padding:0 4px; }
.crop__stage{
  flex:1; position:relative; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  touch-action:none; user-select:none; -webkit-user-select:none;
}
/* The crop window is never resizable by hand — a free transform
   lets couples produce something badly composed and there is no way
   to fix it after the invitations are sent. Its SHAPE, though, is
   whatever the chosen design's slot is, and its SIZE is as much of
   the stage as will fit: both are set in pixels by sizeCropWindow()
   in editor.html, because fitting a given ratio inside a box in
   both directions at once is not something one CSS rule can say. */
.crop__win{
  position:relative; width:200px; height:250px;
  overflow:hidden; border-radius:10px; box-shadow:0 0 0 9999px rgba(20,20,20,.62);
}
.crop__win img{
  position:absolute; top:50%; left:50%; max-width:none;
  transform-origin:center; will-change:transform; pointer-events:none;
}
.crop__grid{ position:absolute; inset:0; pointer-events:none; }
.crop__grid::before,.crop__grid::after{
  content:''; position:absolute; inset:0; border:0 solid rgba(255,255,255,.35);
}
.crop__grid::before{ border-inline-width:1px; inset-inline:33.33% 33.33%; }
.crop__grid::after{ border-block-width:1px; inset-block:33.33% 33.33%; }
.crop__ft{
  padding:16px 18px calc(18px + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; gap:14px;
  width:100%; max-width:520px; margin-inline:auto;
}
.crop__hd{ width:100%; max-width:520px; margin-inline:auto; }
.crop__zoom{ display:flex; align-items:center; gap:12px; color:#fff; }
.crop__zoom input{ flex:1; accent-color:var(--clay); }
.crop__hint{ color:rgba(255,255,255,.6); font-size:12.5px; text-align:center; margin:0; }
.crop__ft .btn{ width:100%; }

/* --- sticky bottom bar --- */
/* A fixed bar spans the window. `max-width:900px; margin:0 auto` on a
   fixed element does not centre a bar inside the window — it makes a
   900px-wide floating slab with the page scrolling past on both
   sides, which on a desktop screen reads as a stray white rectangle
   sitting on top of the invitation preview.

   The background has to reach the edges and only the CONTENT is
   capped, so the cap goes in the padding. */
.ed__foot{
  position:fixed; inset-inline:0; bottom:0; z-index:60;
  background:var(--paper); border-top:1px solid var(--line);
  padding:12px max(18px, calc((100% - 900px) / 2)) calc(12px + env(safe-area-inset-bottom));
  display:flex; gap:10px;
}
.ed__foot .btn{ flex:1 1 0; width:auto; min-width:0; margin:0; }
.ed__foot .btn--out{ flex:0 0 auto; padding-inline:20px; }

@media (min-width:900px){
  .ed__tabs{ display:none; }
  .ed__body{ display:grid; grid-template-columns:1fr 380px; gap:8px;
             max-width:1080px; margin:0 auto; width:100%; align-items:start; }
  /* Both halves are always on screen here, so the tabs are gone and the
     `hidden` attribute they toggle is meaningless. It has to be beaten
     explicitly: `.ed__phone[hidden]` is a class plus an attribute, which
     out-specifies a bare class, so the plainer rule below never won and
     the preview panel stayed hidden at every width — leaving the editor
     as a narrow column of controls with an empty half beside it. */
  .ed__pane, .ed__phone,
  .ed__pane[hidden], .ed__phone[hidden]{ display:block !important; padding-bottom:24px; }
  /* fill the grid track. Without this the pane sizes to its content and
     the controls collapse into a narrow strip with dead space beside them */
  .ed__pane{ width:100%; justify-self:stretch; margin-inline:0; }
  /* `display:block !important` above also cancelled the base rule's
     `display:flex; justify-content:center`, so the phone sat against
     the inner edge of its column instead of in the middle of it.
     Centre the frame itself rather than fighting the override. */
  .ed__phone{ position:sticky; top:calc(var(--header-h) + 96px); }
  .ed__phone .ed__frame{ margin-inline:auto; }
  .ed__foot{ padding-inline:max(18px, calc((100% - 1080px) / 2)); }
}

/* admin: the extra images shown on a design's detail page */
.adm-gal{ display:flex; flex-wrap:wrap; gap:8px; margin-top:6px; }
.adm-gal__i{ position:relative; width:64px; height:80px; border-radius:8px;
  overflow:hidden; background:var(--wash); border:1px solid var(--line); }
.adm-gal__i img{ width:100%; height:100%; object-fit:cover; }
.adm-gal__i button{
  position:absolute; top:2px; left:2px;      /* physical: always the far corner in RTL */
  width:19px; height:19px; border-radius:50%; border:none; cursor:pointer;
  background:rgba(20,20,20,.62); color:#fff; font-size:13px; line-height:1; padding:0;
}
.adm-gal__add{
  width:64px; height:80px; border-radius:8px; cursor:pointer;
  border:1px dashed var(--line-strong); background:var(--wash);
  color:var(--t3); font-size:22px; line-height:1;
}

/* ============================================================
   Guest list — detail sheet and import wizard
   ============================================================ */
.sheet--tall{ max-height:92vh; }

.gd__badges{ display:flex; gap:7px; flex-wrap:wrap; margin-bottom:18px; }
.gd__hist{ list-style:none; margin:8px 0 0; padding:0; font-size:13px; color:var(--t2); }
.gd__hist li{ padding:7px 0; border-bottom:1px solid var(--line-2); }
.gd__hist li:last-child{ border-bottom:none; }
.gd__hist li.is-off{ color:var(--t3); }

.imp__sum{ display:flex; gap:10px; }
.imp__n{
  flex:1; text-align:center; padding:16px 8px; border-radius:12px;
  font-size:28px; font-weight:700; line-height:1;
}
.imp__n span{ display:block; font-size:12.5px; font-weight:400; margin-top:6px; }
.imp__n--ok{ background:var(--clay-soft); color:var(--clay-txt); }
.imp__n--skip{ background:var(--wash); color:var(--t2); }
.imp__list{
  list-style:none; margin:8px 0 0; padding:0;
  font-size:13px; color:var(--t2); line-height:1.7;
}
.imp__list li{ padding:6px 0; border-bottom:1px solid var(--line-2); }
.imp__list li:last-child{ border-bottom:none; }
.imp__list b{ color:var(--t1); font-weight:600; }

/* ============================================================
   Messages — guest picker and the one-at-a-time send queue
   ============================================================ */
.pick__bulk{ display:flex; gap:16px; margin-bottom:10px; font-size:13px; }
.pick__row{
  display:flex; align-items:center; gap:11px; padding:11px 2px;
  border-bottom:1px solid var(--line-2); cursor:pointer;
}
.pick__row:last-child{ border-bottom:none; }
.pick__row.is-off{ opacity:.45; cursor:default; }
.pick__row input{ width:19px; height:19px; accent-color:var(--clay); flex:none; }
.pick__t{ flex:1; min-width:0; }
.pick__t b{ display:block; font-size:14.5px; font-weight:500; }
.pick__t span{ font-size:12.5px; color:var(--t2); }

.qbar{ height:5px; border-radius:3px; background:var(--wash); overflow:hidden; }
.qbar span{ display:block; height:100%; background:var(--clay);
  transition:width .35s var(--ease); }
.qcard{
  display:flex; align-items:center; gap:13px; padding:16px;
  background:var(--wash); border-radius:14px;
}
.qcard__t b{ display:block; font-size:17px; font-weight:600; }
.qcard__t span{ font-size:13.5px; color:var(--t2); direction:ltr; display:block; text-align:start; }

/* the delete-event warning */
.danger{
  background:#FDF3F1; border:1px solid #F0DAD4; border-radius:12px;
  padding:16px; font-size:13.5px; line-height:1.8; color:#8C3323;
}
.danger p{ margin:0 0 8px; }
.danger ul{ margin:0; padding-inline-start:18px; }
.danger li{ margin-bottom:4px; }

/* ============================================================
   THE MENU DRAWER
   The hamburger used to be decorative. Every app screen is now
   one tap from every other one.
   ============================================================ */
/* ---------- the menu belongs to a signed-in account ----------
   `unknown` hides it too: the answer arrives a moment after the page
   does, and a menu of someone's private screens must not be visible
   first and withdrawn second. See markAuth() in ui.js. */
/* Nothing is shown until markAuth() has answered. A menu of
   somebody's private screens must never be visible first and
   withdrawn second, and neither must an account icon that points at
   a dashboard the visitor has no account for. */
html[data-auth="unknown"] [data-nav-open],
html[data-auth="unknown"] .hd__ic--auth-in,
html[data-auth="unknown"] .hd__ic--auth-out{ display:none; }

/* the account icon: one destination, chosen by who is asking */
html[data-auth="out"] .hd__ic--auth-in,
html[data-auth="in"]  .hd__ic--auth-out{ display:none; }

/* the drawer carries both menus; each state shows its own */
html[data-auth="out"] .nav__list--in,
html[data-auth="out"] .nav__ft--in,
html[data-auth="in"]  .nav__list--out,
html[data-auth="unknown"] .nav__list--out{ display:none; }
/* the permanent desktop sidebar is the private drawer, and a
   stranger gets neither it nor the gutter it reserves */
html[data-auth="out"] body.has-nav{ padding-right:0; }
html[data-auth="out"] body.has-nav .nav{ display:none !important; }

.nav-bg{
  position:fixed; inset:0; z-index:198; background:rgba(20,20,20,.42);
  opacity:0; pointer-events:none; transition:opacity .26s var(--ease);
}
.nav-bg.is-open{ opacity:1; pointer-events:auto; }
.nav{
  position:fixed; top:0; bottom:0; z-index:199;
  /* PHYSICAL right, deliberately: the hamburger sits on the right on
     an RTL page, and the drawer must come from under it. Using a
     logical property here put it on the wrong side. */
  right:0; width:min(84vw, 320px);
  background:var(--paper); border-inline-start:1px solid var(--line);
  display:flex; flex-direction:column;
  transform:translateX(101%);
  transition:transform .3s var(--ease);
  padding-bottom:env(safe-area-inset-bottom);
}
.nav.is-open{ transform:none; }
.nav__hd{
  height:var(--header-h); flex:none; display:flex; align-items:center;
  justify-content:space-between; padding:0 18px; border-bottom:1px solid var(--line-2);
}
.nav__list{ flex:1; overflow-y:auto; padding:10px 0; }
.nav__ft{ flex:none; border-top:1px solid var(--line-2); padding:10px 0; }
.nav__i{
  display:flex; align-items:center; gap:13px; width:100%;
  padding:14px 20px; font-size:15px; color:var(--t1);
  background:none; border:none; cursor:pointer; text-align:start;
  font-family:inherit;
}
.nav__i:hover{ background:var(--wash); }
.nav__i.is-on{ color:var(--clay-txt); font-weight:600; background:var(--clay-soft); }
.nav__ic{
  width:22px; height:22px; flex:none; color:var(--t3);
  display:flex; align-items:center; justify-content:center;
}
.nav__i.is-on .nav__ic{ color:var(--clay); }

/* ============================================================
   Phone frame — shows a real invitation in an iframe rather than
   a flat screenshot. Used on the "ready" screen.
   ============================================================ */
.pframe{
  width:min(74vw, 268px);
  border-radius:30px; padding:8px; background:#141414;
  box-shadow:0 18px 44px rgba(20,20,20,.22), 0 2px 6px rgba(20,20,20,.14);
  position:relative;
}
/* the speaker notch, drawn rather than imaged */
.pframe::before{
  content:''; position:absolute; top:16px; left:50%; transform:translateX(-50%);
  width:52px; height:5px; border-radius:3px; background:#2c2c2c; z-index:2;
}
/* The iframe inside is a real 390px phone, shrunk with a transform.
   Scaling the picture keeps the invitation's true layout; sizing the
   iframe down would re-flow it into something no guest ever sees. */
.pframe__vp{
  border-radius:24px; overflow:hidden; background:var(--wash);
  width:100%; position:relative;
}
/* PHYSICAL top/left, and absolutely positioned, on purpose.
   Left in normal flow the iframe starts at the RIGHT edge on an RTL
   page, so scaling from `top left` pushed the whole invitation out of
   the frame and left a blank band. Pinning it to the physical corner
   makes the scale behave the same in both directions. */
.pframe__f{
  position:absolute; top:0; left:0;
  border:0; display:block; transform-origin:top left;
}
/* the screen that replaces the signup form while the confirmation
   email is out — see showCheckEmail() in setup/account.html */
.mailwait{ text-align:center; display:flex; flex-direction:column; align-items:center; gap:12px; }
.mailwait__ic{
  width:56px; height:56px; border-radius:50%; display:grid; place-items:center;
  background:var(--wash); color:var(--clay); margin-bottom:4px;
}
.mailwait__ic svg{ width:24px; height:24px; }
.mailwait .lead{ margin:0; }
.mailwait__to{ word-break:break-all; }
.mailwait .btn{ width:auto; padding-inline:28px; margin-top:6px; }

.pframe__gone{
  display:flex; flex-direction:column; gap:7px; align-items:center; justify-content:center;
  text-align:center; padding:26px 18px; min-height:180px;
  background:var(--wash); border:1px dashed var(--line-strong); border-radius:16px;
  color:var(--t2); font-size:12.5px; line-height:1.6;
}
.pframe__gone b{ color:var(--ink); font-size:13.5px; }
.pframe__gone span{ word-break:break-all; }

.ready__phone{ display:flex; justify-content:center; margin:8px 0 14px; }

/* ============================================================
   ============================================================
   BIGGER SCREENS

   Everything above this line is the mobile design and is not
   touched by anything below — these are additive overrides that
   only start at 768px. A phone never reaches them.

   768px  tablets: wider column, more items per row
   1100px desktop: the menu becomes a permanent sidebar and each
          screen uses the width instead of sitting in a ribbon
   ============================================================
   ============================================================ */

@media (min-width:768px){
  :root{ --header-h:76px; }

  .wrap{ max-width:720px; padding:36px 28px 64px; }
  .wrap--flush{ max-width:720px; }

  .h1{ font-size:42px; }
  .h2{ font-size:31px; }
  .lead{ font-size:16px; }

  /* gallery: three across reads as a collection rather than a list */
  .grid{ grid-template-columns:repeat(3,1fr); gap:18px; }

  .tiles{ grid-template-columns:repeat(3,1fr); gap:14px; }
  .tile{ padding:22px 14px; font-size:14px; }

  .qa__btn{ font-size:13px; padding:13px 10px; }

  /* the entry screen has room to breathe. Still the stacked layout —
     the split only starts at 900px, below which two columns would
     leave a 260px-wide headline beside a 260px-wide photograph. */
  .hero{ padding:0 40px; }
  .hero__in{ padding-top:13vh; }
  /* one knob for the desktop headline, stepped down here rather than
     given a second number the admin panel would have to know about */
  .hero__h{ font-size:calc(var(--fs-hero-d,68px) * .82); }
  .hero__p{ font-size:16px; max-width:440px; }
  .hero__acts{
    flex-direction:row; justify-content:center; gap:14px;
    max-width:520px; margin:0 auto;
  }
  .hero__acts .btn{ width:auto; min-width:210px; }

  .pframe{ width:290px; }

  .gbtns{ grid-template-columns:auto auto; justify-content:start; }
  .gbtns .btn{ width:auto; padding-inline:26px; }

  .sheet{ max-width:560px; border-radius:20px; }

  /* a wider card gets bigger thumbnails, or a handful of small squares
     look stranded on 600-odd pixels of strip */
  .gal__th{ width:76px; }
  .gal__thumbs{ gap:10px; }
  .ed__cover, .ed__covacts{ max-width:320px; }

  /* ---------- pricing ----------
     Side by side from a tablet up, as on the marketing site: you can
     only compare two prices you can see at once. */
  body[data-page="package"] .wrap{ max-width:1088px; }
  .kp-plans{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px; }
  .kp-plan{ padding:32px; border-radius:22px; }
  .kp-plan h2{ font-size:23px; }
  .kp-desc{ min-height:53px; }
  .kp-price{ margin-top:24px; }
  .kp-amount{ font-size:42px; }
  .kp-rule{ margin:26px 0; }
  .kp-service{ flex-direction:row; align-items:center; justify-content:space-between;
               gap:32px; margin-top:32px; padding-top:28px; }
  .kp-contact{ width:auto; flex-shrink:0; min-width:160px; margin:0; }
}

/* ============================================================
   ENTRY HERO · the split layout  (desktop, 900px and up)

   Set in /admin/ → עיצוב האתר → מסך הכניסה → פריסה. The default,
   and the one in the mockup: the sentence on the left of a dark
   screen, the photograph filling the right, a coral disc behind
   the figures.

   PHYSICAL right/left throughout, deliberately. The photograph
   belongs on the physical right of the screen in the mockup, and
   logical properties would put it on the reading-start side, which
   on this RTL page is the right on one and the left on the other.
   Nothing here is a typo.
   ============================================================ */
@media (min-width:900px){
  [data-hero-layout="split"] .hero{ padding:0; }

  [data-hero-layout="split"] .hero__grid{
    display:grid; grid-template-columns:1.05fr 1fr;
    align-items:center; gap:40px;
    padding-inline:clamp(34px, 6vw, 104px);
  }

  /* Column 2 is the LEFT column on an RTL page, which is where the
     mockup puts the words. The lines are flush left against the
     photograph's fade, so the block reads as one edge. */
  /* EVERY box in this column is pinned to the same physical left edge,
     and each one needs saying separately because the page is RTL and
     each has a different reason to drift right:

       the block   — a max-width grid item aligns to the inline start,
                     which is the right, so `justify-self:end`
       the sentence— a narrow block keeps its free space on the inline
                     start, so the auto margin goes on the physical right
       the buttons — a column flex container's cross-start is the right,
                     so they hug the left at `flex-end`

     Get any one of them wrong and the layout still looks deliberate,
     just misaligned by 120px. That is what this comment is for. */
  /* ------------------------------------------------------------
     ONE EDGE.

     The headline, the sentence under it and both buttons used to
     flush LEFT — `text-align:left` on Hebrew, plus `align-items:
     flex-end` on the buttons, which is also left once RTL flips the
     cross axis. Left is the wrong edge for Hebrew: it is where each
     line happens to END, so the edge the eye actually starts from
     was the ragged one, and the three blocks finished at three
     different places (424px, 495px and 436px on a 1280 screen).

     Everything now flushes to `start` — the right, where a Hebrew
     reader begins — so the headline, the sentence and the buttons
     share a single clean edge. `start`, not `right`, so a template
     rendered in an LTR language flips with it.

     The box gets a real width too. It was shrink-to-fit, so its
     width came from whichever child happened to be widest and the
     headline wrapped inside 400px rather than the 520 it asks for.
     ------------------------------------------------------------ */
  [data-hero-layout="split"] .hero__in{
    grid-column:2; grid-row:1;
    text-align:start; padding-top:0;
    width:min(520px, 100%); max-width:520px; justify-self:end;
  }
  [data-hero-layout="split"] .hero__h{ font-size:var(--fs-hero-d,68px); line-height:1.12; }
  [data-hero-layout="split"] .hero__p{
    margin:22px 0 34px; max-width:430px; font-size:16.5px; color:#CFC8C2;
    margin-inline-start:0; margin-inline-end:auto;   /* ragged edge falls away from the reader */
  }
  [data-hero-layout="split"] .hero__acts{
    flex-direction:column; align-items:flex-start;   /* cross-start = right in RTL */
    margin:0; max-width:none; gap:13px;
  }
  [data-hero-layout="split"] .hero__acts .btn{ width:340px; min-width:0; }

  /* The photograph: a band down the right, dissolving into the dark as
     it travels left so the words never sit on top of it.

     44% and not half: the shipped photo is a phone-shaped portrait, so
     a near-square opening frames nothing but the statues' heads. A
     tall narrow one keeps both figures whole.

     Anchored to the BOTTOM, which is where the subject of this kind of
     photograph is — cropping the empty sky above the figures costs
     nothing and cropping their shoulders costs everything. */
  [data-hero-layout="split"] .hero__img{
    inset:0 0 0 auto; width:44%;
    background-position:center bottom;
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 34%);
            mask-image:linear-gradient(to right, transparent 0, #000 34%);
  }
  /* A scrim shaped for this layout: it deepens toward the seam on
     the left and lets the figures stand at full strength on the
     right, instead of the top-to-bottom veil the phone needs. */
  [data-hero-layout="split"] .hero__img::after{
    background:
      linear-gradient(to right,
        rgba(16,16,16,calc(var(--hero-veil,.72) * .95)) 0%,
        rgba(16,16,16,calc(var(--hero-veil,.72) * .28)) 46%,
        rgba(16,16,16,0) 100%),
      linear-gradient(180deg,
        rgba(16,16,16,calc(var(--hero-veil,.72) * .34)) 0%,
        rgba(16,16,16,0) 40%);
  }

  /* THE MOON.
     Under the photograph, straddling the seam, so it is the faded
     edge of the photograph that reveals it — the same effect as the
     cut-out figures in the mockup, from a rectangular photo. */
  [data-hero-moon="on"][data-hero-layout="split"] .hero__moon{
    display:block; position:absolute; z-index:0;
    top:7%; right:26%;
    width:min(21vw, 290px); aspect-ratio:1; border-radius:50%;
    /* the flat disc first: a browser without color-mix() keeps this
       one and still gets the mockup's composition, just unlit */
    background:var(--moon,#C1705B);
    background:radial-gradient(circle at 42% 38%,
      color-mix(in srgb, var(--moon,#C1705B) 78%, #fff) 0%,
      var(--moon,#C1705B) 62%,
      color-mix(in srgb, var(--moon,#C1705B) 72%, #000) 100%);
    opacity:.95;
  }
  /* a soft halo, so the disc reads as light rather than as a sticker */
  [data-hero-moon="on"][data-hero-layout="split"] .hero__moon::after{
    content:''; position:absolute; inset:-22%;
    border-radius:50%; opacity:.4;
    background:radial-gradient(circle,
      color-mix(in srgb, var(--moon,#C1705B) 45%, transparent) 0%, transparent 68%);
  }

  /* the centred alternative keeps the phone composition, just larger */
  [data-hero-layout="center"] .hero__in{ padding-top:15vh; }
  [data-hero-layout="center"] .hero__h{ font-size:var(--fs-hero-d,68px); }
}

@media (min-width:1100px){
  /* ---------- the sidebar ----------
     The drawer stops being a drawer. PHYSICAL right/padding-right on
     purpose: the menu button lives on the right on an RTL page and
     the panel has to stay under it. */
  body.has-nav{ padding-right:264px; }
  body.has-nav .nav{
    transform:none; width:264px; box-shadow:none;
    border-inline-start:1px solid var(--line);
  }
  body.has-nav .nav-bg{ display:none !important; }
  body.has-nav [data-nav-open]{ display:none; }
  body.has-nav .hd{ padding-inline-start:26px; }

  .wrap{ max-width:760px; }

  /* the sidebar is permanent here, so its own header would be a
     second logo directly under the page's own, and a close button
     for something that cannot close */
  body.has-nav .nav__hd{ display:none; }
  body.has-nav .nav__list{ padding-top:22px; }

  /* ---------- dashboard screens ----------
     Two columns, filled in document order. Anything full-width says
     so. This is deliberately simple: pinning cards to named columns
     left holes whenever a card was empty (no RSVPs yet, no activity
     yet), which is exactly the state a new couple is in. */
  body.has-nav .wrap{
    max-width:1060px;
    display:grid; grid-template-columns:1fr 1fr;
    gap:20px 24px; align-items:start;
  }
  body.has-nav .wrap > .center,
  body.has-nav .wrap > .search,
  body.has-nav .wrap > .fchips,
  body.has-nav .wrap > .gbtns,
  body.has-nav .wrap > .gtable,
  body.has-nav .wrap > .tiles,
  body.has-nav .wrap > .helpbox,
  body.has-nav .wrap > .btn{ grid-column:1 / -1; }

  /* ============================================================
     THE PERSONAL AREA · the dashboard layout

     This is the desktop mockup, and the default. /admin/ →
     עיצוב האתר → האזור האישי can switch it to "stacked", which is
     the phone composition at every width, and can turn the tile row
     and the phone mockup off independently.

     Reading the screen from the top: who this event belongs to and
     what its invitation looks like, the three actions worth taking
     from here, the doors to every management screen, then the two
     things that change on their own — the numbers and the feed.

     Column 1 is the RIGHT column on an RTL page. The mockup puts
     the feed on the right and the numbers on the left, which is why
     `.actcard` is column 1 below and not the other way round.
     ============================================================ */
  html[data-home-layout="dashboard"] body[data-page="home"] .wrap{
    max-width:1100px;
    display:grid; grid-template-columns:1fr 1fr;
    gap:18px 22px; align-items:start;
    /* `dense` is load-bearing. The feed is named to column 1 but comes
       AFTER the numbers card in the markup, and ordinary auto-placement
       never moves backwards — so the two cards landed on separate rows,
       each with an empty column beside it. Dense back-fills the slot
       that is already free. Doing it with an explicit grid-row instead
       would break the moment the tile row is switched off and every row
       number below it shifts up by one. */
    grid-auto-flow:row dense;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .wrap > .center,
  html[data-home-layout="dashboard"] body[data-page="home"] .welcome,
  html[data-home-layout="dashboard"] body[data-page="home"] .tiles,
  html[data-home-layout="dashboard"] body[data-page="home"] .helpbox{ grid-column:1 / -1; }

  /* centred over a 1100px band the heading floats; at the reading
     edge it belongs to the page under it */
  html[data-home-layout="dashboard"] body[data-page="home"] .wrap > .center{ text-align:start; }

  /* ---- the status band: three zones inside one card ---- */
  html[data-home-layout="dashboard"] body[data-page="home"] .welcome{
    padding:26px 30px; margin-top:18px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .welcome__grid{
    display:grid; grid-template-columns:1.05fr .68fr 1fr;
    gap:36px; align-items:center;
  }
  /* the facts stay a stacked list, as in the mockup — a wrapped
     single line reads as a caption, and this is the event itself */
  html[data-home-layout="dashboard"] body[data-page="home"] .welcome__row{
    align-items:center; gap:20px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .welcome__names{ font-size:24px; }

  /* the phone mockup, and the small thumbnail it replaces: never
     both, or the same picture appears twice in one card */
  html[data-home-phone="on"] body[data-page="home"] .welcome__phone{ display:block; }
  html[data-home-phone="on"] body[data-page="home"] .welcome__sh{ display:none; }
  html[data-home-phone="off"] body[data-page="home"] .welcome__grid{
    grid-template-columns:1.35fr 1fr;
  }
  html[data-home-phone="off"] body[data-page="home"] .welcome__sh{
    width:92px; height:118px;
  }

  /* ---- quick actions: the card's third column ---- */
  html[data-home-layout="dashboard"] body[data-page="home"] .qa{
    margin:0; padding:0; border-top:none;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .qa__t{
    text-align:start; margin-bottom:11px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .qa__row{
    flex-direction:column; gap:10px;
  }
  /* `row-reverse` puts the icon at the far end and the label at the
     reading edge, which is the mockup: you read the action, the icon
     confirms it. On an RTL page that is icon-left, label-right. */
  html[data-home-layout="dashboard"] body[data-page="home"] .qa__btn{
    width:100%; flex:none; border-radius:12px;
    flex-direction:row-reverse; justify-content:space-between;
    padding:14px 17px; font-size:13.5px; background:var(--bg);
  }

  /* ---- the tile row ---- */
  html[data-home-tiles="on"] body[data-page="home"] .tiles{
    display:grid; grid-template-columns:repeat(auto-fit, minmax(148px, 1fr));
    gap:14px; margin-top:2px;
  }
  /* Off by choice, not by accident: every tile is also a permanent row
     in the sidebar, so hiding them costs no destination. */
  html[data-home-tiles="off"] body[data-page="home"] .tiles{ display:none; }

  /* ---- the two live cards ---- */
  html[data-home-layout="dashboard"] body[data-page="home"] .actcard{ grid-column:1; margin-top:0; }
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpcard{ grid-column:2; margin-top:0; }
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpcard{ padding:22px; }
  /* the donut moves to the far side of its card and the numbers take
     the reading edge, matching the mockup. Explicit rows because the
     two children are being reordered, not just re-sized. */
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpgrid{
    grid-template-columns:1fr 118px; gap:18px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpgrid > #donut{
    grid-column:2; grid-row:1;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpnums{
    grid-column:1; grid-row:1; gap:16px 10px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .rsvpcard__t,
  html[data-home-layout="dashboard"] body[data-page="home"] .actcard .rsvpcard__t{
    text-align:start;
  }

  /* ---- support ---- */
  html[data-home-layout="dashboard"] body[data-page="home"] .helpbox{
    text-align:center; padding:34px 26px;
  }
  html[data-home-layout="dashboard"] body[data-page="home"] .helpbox .btn{
    width:auto; min-width:250px; margin:0 auto; padding-inline:30px;
  }

  /* ---- the stacked alternative ----
     One readable column at any width. Nothing is hidden; it is the
     phone screen, given a comfortable measure. */
  html[data-home-layout="stacked"] body[data-page="home"] .wrap{
    display:block; max-width:560px;
  }

  /* guests: one wide column — the table is the screen */
  body[data-page="guests"] .wrap{ grid-template-columns:1fr; max-width:1180px; }
  body[data-page="guests"] .gbtns{ justify-content:flex-start; }
  .ghead, .grow{ grid-template-columns:2fr 1fr .8fr 1.4fr; padding-inline:20px; }

  /* settings is a form: two columns of cards, but each stays readable */
  body[data-page="settings"] .wrap > section{ grid-column:1 / -1; }
  body[data-page="settings"] .wrap{ max-width:820px; grid-template-columns:1fr; }

  /* ---------- the setup flow on a wide screen ----------
     These follow the desktop mockups. The rule throughout: the thing
     you are deciding about goes on the left, the thing you are doing
     goes on the right, and neither column is allowed to grow so wide
     that a line of Hebrew becomes tiring to read.

     Column 1 is the RIGHT column on an RTL page. That is not a typo
     anywhere below — it is why the "doing" side is column 1. */

  /* --- product page: the gallery left, the decision right --- */
  body[data-page="design"] .wrap{
    max-width:1180px;
    display:grid; grid-template-columns:1fr 1fr;
    gap:0 44px; align-items:start; grid-auto-rows:min-content;
  }
  /* EVERY item needs an explicit row here, not just a column.
     Naming the column alone still lets auto-placement give each item
     a row of its own, so the two columns advance in lockstep down the
     page: the title sits level with the bottom of the artwork and the
     accordion ends up a screen and a half below it, with a column of
     dead space beside each. The rows below interleave the two tracks
     so both start at the top and the shorter one leaves the gap. */
  body[data-page="design"] .crumb{ grid-column:1 / -1; grid-row:1; }

  /* column 2 is the LEFT column on an RTL page — the gallery side */
  body[data-page="design"] .dt__media{
    grid-column:2; grid-row:2 / span 8;
    position:sticky; top:calc(var(--header-h) + 24px);
    align-self:start;
  }

  body[data-page="design"] .dt__badge{ grid-column:1; grid-row:2; justify-self:start; }
  body[data-page="design"] .dt__name { grid-column:1; grid-row:3; }
  body[data-page="design"] .dt__tags { grid-column:1; grid-row:4; }
  body[data-page="design"] .dt__desc { grid-column:1; grid-row:5; }
  body[data-page="design"] .dt__feats{ grid-column:1; grid-row:6; }
  body[data-page="design"] .acc__ttl { grid-column:1; grid-row:7; }
  body[data-page="design"] .acc      { grid-column:1; grid-row:8; }
  body[data-page="design"] .dt__acts { grid-column:1; grid-row:9; }

  body[data-page="design"] .dt__name{ font-size:44px; margin-top:2px; }
  body[data-page="design"] .dt__desc{ font-size:15px; }
  /* the three promises sit in a bordered band, as in the mockup */
  body[data-page="design"] .dt__feats{
    border-block:1px solid var(--line); padding:18px 0; margin:22px 0 4px;
  }
  /* a band, not three cards. The phone stylesheet gives each promise
     its own box because they stack there; side by side inside a ruled
     band that is a frame inside a frame. */
  body[data-page="design"] .dt__feat{
    border:0; border-radius:0; background:none; padding:0 6px;
  }
  body[data-page="design"] .dt__feat + .dt__feat{
    border-inline-start:1px solid var(--line);
  }
  body[data-page="design"] .gal__stage{ aspect-ratio:4/3.6; }
  body[data-page="design"] .acc__ttl{ margin-top:26px; }

  /* --- payment: what you are buying right, the card form left ---
     Column 1 is the RIGHT column on an RTL page, so the summary —
     the thing being confirmed — is the first column read. */
  body[data-page="payment"] .wrap{
    max-width:1000px;
    display:grid; grid-template-columns:1fr 1fr;
    gap:26px 40px; align-items:start;
  }
  body[data-page="payment"] .wrap > .center{ grid-column:1 / -1; margin-bottom:6px; }
  body[data-page="payment"] .pay__sum { grid-column:1; }
  body[data-page="payment"] .pay__form{ grid-column:2; }
  body[data-page="payment"] .pay__form .lead{ text-align:start; margin:0 0 14px; }
  /* the grid gap sets the distance from the title; the phone margins
     would add to it and knock the two columns out of line */
  body[data-page="payment"] .pay__sum,
  body[data-page="payment"] .pay__form{ margin-top:0; }

  /* --- the finished invitation: the phone left, what to do next right --- */
  body[data-page="customize-3"] .wrap{
    max-width:1000px;
    display:grid; grid-template-columns:1fr 1fr;
    gap:10px 40px; align-items:start;
  }
  body[data-page="customize-3"] .wrap > .center:first-child{ grid-column:1 / -1; }
  body[data-page="customize-3"] .ready__phone{
    grid-column:2; grid-row:2 / span 20; margin:0;
    position:sticky; top:calc(var(--header-h) + 24px);
  }
  body[data-page="customize-3"] .wrap > *:not(.ready__phone):not(.center:first-child){
    grid-column:1;
  }

  /* --- customize-2: steps, with a live preview beside them on desktop --- */
  body[data-page="customize-2"] .wrap{ max-width:1180px; }
  body[data-page="customize-2"] .c2{
    display:grid; grid-template-columns:minmax(360px,1fr) 1.15fr;
    gap:32px; align-items:start; margin-top:28px;
  }
  /* the preview is column 1 = the RIGHT column on this RTL page, matching
     the mockup where the phone sits on the right */
  body[data-page="customize-2"] .c2__preview{
    grid-column:1; position:sticky; top:calc(var(--header-h) + 24px);
    background:var(--paper); border:1px solid var(--line);
    border-radius:16px; padding:20px;
  }
  body[data-page="customize-2"] .c2__steps{ grid-column:2; }

  /* --- sign-up: brand panel beside the form, matching the mockup --- */
  body[data-page="account"] .wrap{ max-width:1080px; }
  body[data-page="account"] .acct{
    display:grid; grid-template-columns:1fr 1fr; gap:48px; align-items:center;
  }
  /* Both need an explicit ROW, not just a column. `.acct__brand` is
     declared column 2 and comes FIRST in the markup, so grid
     auto-placement moved its cursor past row 1 and dropped the form
     on a fresh row below — the panel at the top of the screen and the
     sign-up form a full screen beneath it, each with a column of
     white beside it. Same trap as the product page. */
  body[data-page="account"] .acct__form{
    grid-column:1; grid-row:1;
    max-width:440px; width:100%; justify-self:center;
  }
  body[data-page="account"] .acct__brand{ grid-column:2; grid-row:1; display:block; }

  /* login keeps one centred column — nothing to show beside it */
  body[data-page="login"] .wrap{ max-width:520px; }

  /* --- customize-1: the event form as a single card ---
     On a phone the form is the page, so it needs no container. Here
     it is four short fields adrift in a very wide viewport, which
     reads as an unfinished screen. The card gives them an edge to
     sit against, and the label moves beside its field rather than
     above it: at this width a stacked label wastes the horizontal
     room and drags the form twice as long as it needs to be. */
  body[data-page="customize-1"] .wrap{ max-width:840px; }
  body[data-page="customize-1"] .c1__fields{
    background:var(--paper); border:1px solid var(--line);
    border-radius:var(--r-card); padding:34px 40px;
  }
  body[data-page="customize-1"] .c1__fields .f{
    display:grid; grid-template-columns:150px minmax(0,1fr);
    align-items:center; gap:18px; margin-bottom:18px;
  }
  body[data-page="customize-1"] .c1__fields .f:last-child{ margin-bottom:0; }
  body[data-page="customize-1"] .c1__fields .f__lab{ margin-bottom:0; font-size:14px; }
  body[data-page="customize-1"] .wrap > .btn{
    max-width:340px; margin-inline:auto; margin-top:24px;
  }

  .grid{ grid-template-columns:repeat(4,1fr); }
  body[data-page="collection"] .wrap{ max-width:1180px; }

  body[data-page="package"] .wrap{ max-width:1140px; }
  body[data-page="package"] #list{ grid-template-columns:repeat(3,1fr); gap:20px; }

  .hero__h{ font-size:var(--fs-hero-d,68px); }
  .pframe{ width:310px; }

  /* the editor already had its own two-column layout at 900px;
     give it the extra room rather than a second set of rules */
  .ed__body{ max-width:1240px; grid-template-columns:1fr 420px; gap:28px; }
  .ed__pane{ max-width:640px; }
  .ed__foot{ padding-inline:max(18px, calc((100% - 1240px) / 2)); }
}

/* ============================================================
   customize-2 preview panel — base styles (all widths)
   The panel itself is hidden on phones; only from 900px up does the
   grid above place it beside the steps. Everything here is inert until
   then because the .c2 grid collapses to one column on mobile.
   ============================================================ */
.c2__preview{ display:none; }
.c2__pvhead{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
.c2__pvttl{ font-size:14px; color:var(--t2); }
.c2__pvtabs{ display:flex; gap:6px; }
.c2__pvtab{
  display:grid; place-items:center; width:34px; height:30px;
  border:1px solid var(--line); border-radius:8px; background:var(--bg);
  color:var(--t2); cursor:pointer; transition:all .15s;
}
.c2__pvtab.is-on{ border-color:var(--clay-btn); color:var(--clay-btn); background:#fff; }
.c2__pvstage{ margin:0 auto; max-width:300px; transition:max-width .25s ease; }
.c2__pvstage--desktop{ max-width:100%; }
.c2__pvnote{ text-align:center; font-size:12px; color:var(--t3); margin-top:12px; }

@media (min-width:900px){
  /* the grid in the desktop block reveals the panel; make its contents show */
  body[data-page="customize-2"] .c2__preview{ display:block; }
}

/* ============================================================
   account brand panel — base styles (hidden until 900px)
   ============================================================ */
.acct__brand{ display:none; text-align:center; }
.acct__logo{ height:34px; width:auto; margin:0 auto 22px; display:block; }
.acct__tag{ font-family:var(--f-serif); font-size:30px; color:var(--ink); line-height:1.2; }
.acct__tag .clay{ color:var(--clay-text); }
.acct__sub{ font-size:14px; color:var(--t2); line-height:1.7; max-width:340px; margin:14px auto 0; }
.acct__phone{ margin:28px auto 0; max-width:260px; }
.acct__phone img{ width:100%; border-radius:20px; box-shadow:0 30px 60px -28px rgba(40,28,22,.5); }


/* ============================================================
   confirmation — the two-card "ready to share" screen
   Mobile: everything stacks. Desktop: the two cards sit side by side.
   ============================================================ */
.cf{ max-width:520px; margin:0 auto; }
.cf__head{ text-align:center; }
.cf__ref{ display:inline-block; background:var(--paper); border:1px solid var(--line);
  border-radius:12px; padding:12px 26px; margin-top:16px; }
.cf__cards{ display:grid; gap:16px; margin-top:26px; }
.cf__card{ background:var(--paper); border:1px solid var(--line); border-radius:16px;
  padding:24px; text-align:center; }
.cf__ct{ font-family:var(--f-serif); font-size:21px; color:var(--ink); margin-bottom:6px; }
.cf__paic{ width:56px; height:56px; margin:0 auto 12px; display:grid; place-items:center;
  border:1.5px solid var(--clay-btn); border-radius:50%; color:var(--clay-btn); }
.cf__paic svg{ width:26px; height:26px; }
.cf__tiles{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:18px; }
.cf__tile{ background:var(--bg); border:1px solid var(--line); border-radius:12px;
  padding:14px 10px; text-align:center; font-size:12.5px; color:var(--t2); line-height:1.5; }
.cf__tile span:first-child{ display:block; color:var(--clay-btn); margin-bottom:6px; }
.cf__tile svg{ width:22px; height:22px; margin:0 auto; }

.cf__card--solo{ max-width:560px; margin:26px auto 0; }

@media (min-width:900px){
  body[data-page="confirmation"] .wrap{ max-width:640px; }
}

/* ============================================================
   product page — "what's included" expandable rows
   Each row makes it obvious it opens: a chevron that rotates, and a
   body that animates from zero height. Replaces the old flat list
   that gave no signal it was interactive.
   ============================================================ */
.acc__ttl{ font-family:var(--f-body); font-weight:600; font-size:19px; color:var(--ink); margin:22px 0 12px; }
.accrow{ border-bottom:1px solid var(--line); }
.accrow__hd{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  gap:12px; padding:16px 16px; background:none; border:none; cursor:pointer;
  font:inherit; color:var(--ink); text-align:start;
}
.accrow__t{ font-size:15px; }
.accrow__ch{ color:var(--t2); display:grid; place-items:center; flex:none;
  transition:transform .32s cubic-bezier(.4,0,.2,1); }
.accrow__ch svg{ width:18px; height:18px; }
.accrow.is-open .accrow__ch{ transform:rotate(180deg); }
/* Only the row height moves. The padding used to switch on the moment
   a row opened, so the space under the text jumped in before the
   animation ran and the whole thing felt like it stuck. Now the padding
   lives inside a clipped wrapper and is always there; the grid row
   clips it from 0 to full. */
.accrow__bd{
  display:grid; grid-template-rows:0fr;
  transition:grid-template-rows .32s cubic-bezier(.4,0,.2,1);
}
.accrow.is-open .accrow__bd{ grid-template-rows:1fr; }
.accrow__in{ overflow:hidden; min-height:0; }
.accrow__in > p{
  margin:0; padding:0 16px 16px; font-size:13.5px; line-height:1.7; color:var(--t2);
  opacity:0; transition:opacity .25s ease;
}
.accrow.is-open .accrow__in > p{ opacity:1; transition-delay:.06s; }
@media (prefers-reduced-motion: reduce){
  .accrow__bd, .accrow__in > p, .accrow__ch{ transition:none; }
}

/* ============================================================
   THE COUPLE'S OWN RSVP QUESTIONS

   Rendered into whatever template the couple chose, so these stay
   deliberately plain: they inherit the invitation's type and colour
   and only supply spacing. Each design's own `.field` / `.select`
   rules do the rest, which is why the markup reuses those names.
   ============================================================ */
.k-extra{ display:flex; flex-direction:column; gap:12px; margin:14px 0; }
.k-extra__q{ display:flex; flex-direction:column; gap:6px; text-align:start; }
.k-extra__q label{ font-size:13px; opacity:.8; }
.k-extra[hidden]{ display:none; }

.meal{ display:flex; align-items:center; gap:10px; margin-bottom:9px; }
.meal__n{ font-size:12.5px; opacity:.75; flex:none; min-width:72px; text-align:start; }
.meal select{ flex:1; min-width:0; }

/* ============================================================
   The WhatsApp card preview in the editor.
   A real proportioned mock of the link preview, not a diagram —
   the couple should recognise it from their own chats.
   ============================================================ */
.wa-card{
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--paper); border:1px solid var(--line); border-radius:10px;
  max-width:340px; margin:14px 0 18px;
}
/* flex:none matters — as a flex item in a column container the box
   was free to grow past its own aspect-ratio, and a portrait cover
   stretched the mock several screens tall. */
.wa-card__img{
  flex:none; width:100%; aspect-ratio:1200/630; overflow:hidden;
  background:var(--wash);
  display:grid; place-items:center; color:var(--t3); font-size:12.5px;
}
.wa-card__img img{ width:100%; height:100%; object-fit:cover; display:block; }
.wa-card__tx{ padding:9px 12px 11px; }
.wa-card__t{ font-size:14px; font-weight:600; line-height:1.35; }
.wa-card__d{
  font-size:12.5px; color:var(--t2); line-height:1.5; margin-top:3px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.wa-card__u{ font-size:11.5px; color:var(--t3); margin-top:5px; direction:ltr; text-align:start; }


/* ============================================================
   LEGAL PAGES · terms and privacy
   Long-form reading, so the measure is capped and the rhythm is
   looser than the app's. Nothing decorative: these are read when
   somebody is checking something specific.
   ============================================================ */
.legal{ max-width:660px; }
.legal__h1{ font-family:var(--f-serif); font-size:clamp(26px,5vw,36px); font-weight:500;
  line-height:1.25; margin:0 0 6px; }
.legal__meta{ font-size:12.5px; color:var(--t3); margin:0 0 22px; }
.legal__lead{ font-size:15.5px; line-height:1.85; color:var(--ink); margin:0 0 26px; }
.legal h2{ font-size:16.5px; font-weight:600; margin:30px 0 8px; }
.legal p, .legal li{ font-size:14.5px; line-height:1.85; color:var(--t2); }
.legal p{ margin:0 0 10px; }
.legal ul{ margin:0 0 10px; padding-inline-start:20px; }
.legal li{ margin-bottom:6px; }
.legal b{ color:var(--ink); font-weight:600; }
.legal a{ color:var(--clay-txt); }
.legal__foot{ margin-top:34px; padding-top:16px; border-top:1px solid var(--line); font-size:13.5px; }

/* the quiet line of links at the foot of the public pages */
.legalbar{
  display:flex; flex-wrap:wrap; gap:6px 16px; justify-content:center; align-items:center;
  margin-top:40px; padding:22px 18px 30px; border-top:1px solid var(--line-2);
  font-size:12.5px; color:var(--t3);
}
.legalbar a{ color:var(--t2); text-decoration:none; }
.legalbar a:hover{ color:var(--ink); text-decoration:underline; }
/* The 40px above is right after ordinary page content and wrong under
   a full-bleed hero: it showed as a band of page background between
   the photograph and the footer, so the image looked cut off short of
   the bottom of the screen. Directly after the hero, the footer
   starts where the picture ends. */
.hero + .legalbar{ margin-top:0; }


/* ============================================================
   FULL-SCREEN IMAGE VIEWER

   The product page sells a picture, and on a phone the picture was
   324px wide with no way to look closer: tapping did nothing, the
   page itself does not pinch inside a fixed layout, and the only
   button that said "full view" actually opened the live demo.
   Tap the picture, get the picture — pinch, drag, swipe, close.
   ============================================================ */
.lb{
  position:fixed; inset:0; z-index:200; display:none;
  background:rgba(18,16,15,.97);
  align-items:center; justify-content:center;
  touch-action:none;                 /* we drive pinch and pan ourselves */
  overscroll-behavior:contain;
}
.lb.is-open{ display:flex; }
.lb__img{
  max-width:100%; max-height:100%; display:block;
  transform-origin:center center; will-change:transform;
  -webkit-user-select:none; user-select:none; -webkit-user-drag:none;
  transition:transform .22s cubic-bezier(.22,.61,.36,1);
}
.lb__img.is-dragging{ transition:none; }
.lb__x{
  position:absolute; top:calc(12px + env(safe-area-inset-top,0px)); inset-inline-end:14px;
  width:42px; height:42px; border-radius:50%; border:none; padding:0;
  background:rgba(255,255,255,.14); color:#fff; font-size:22px; line-height:1;
  display:grid; place-items:center; cursor:pointer; -webkit-appearance:none; appearance:none;
}
.lb__count{
  position:absolute; bottom:calc(18px + env(safe-area-inset-bottom,0px)); inset-inline:0;
  text-align:center; color:rgba(255,255,255,.72); font-size:12.5px;
  font-variant-numeric:tabular-nums lining-nums; direction:ltr; pointer-events:none;
}
.lb__hint{
  position:absolute; top:calc(20px + env(safe-area-inset-top,0px)); inset-inline-start:16px;
  color:rgba(255,255,255,.6); font-size:12px; pointer-events:none;
}
body.lb-open{ overflow:hidden; }

/* dragging the strip with a mouse, the way a finger already drags it */
.gal__thumbs{ cursor:grab; }
.gal__thumbs.is-grabbing{ cursor:grabbing; scroll-snap-type:none; }
.gal__thumbs.is-grabbing .gal__th{ pointer-events:none; }


/* ============================================================
   WHAT HAPPENS NEXT · the three steps after the invitation is built
   Shown on the "ready" screen, where a couple used to be told the
   invitation was finished and nothing about the guest list.
   ============================================================ */
.next{ list-style:none; margin:0 0 20px; padding:16px 16px 6px; background:var(--paper);
  border:1px solid var(--line); border-radius:16px; }
.next__i{ display:flex; gap:12px; align-items:flex-start; margin-bottom:12px; }
.next__n{ flex:none; width:26px; height:26px; border-radius:50%; display:grid; place-items:center;
  font-size:12.5px; font-weight:600; background:var(--wash); color:var(--t2); border:1px solid var(--line); }
.next__i.is-done .next__n{ background:var(--clay-a11y); border-color:var(--clay-a11y); color:#fff; }
.next__i.is-now  .next__n{ background:var(--ink); border-color:var(--ink); color:#fff; }
.next__i b{ display:block; font-size:14.5px; font-weight:600; color:var(--ink); }
.next__i i{ display:block; font-style:normal; font-size:12.5px; color:var(--t2); line-height:1.6; margin-top:2px; }


/* ============================================================
   THE DESIGN'S BRIEF · replacing artwork drawn in a particular hand

   This has to READ as a control. The first version was a bordered
   box with a line of text in it, and a line of text does not look
   pressable — it was missed entirely. It is now shaped like the
   other controls on the page: a raised row with an icon, two lines
   of label, and a chevron that turns. Closed it is a button; open it
   is a panel hanging off that button.
   ============================================================ */
.prm{ margin-top:14px; }
.prm__sum{
  display:flex; align-items:center; gap:12px;
  min-height:60px; padding:10px 14px;
  background:var(--paper);
  border:1px solid var(--line-strong, var(--line));
  border-radius:14px;
  box-shadow:0 1px 2px rgba(20,20,20,.04);
  cursor:pointer; list-style:none;
  transition:background .18s var(--ease), border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.prm__sum::-webkit-details-marker{ display:none; }
.prm__sum:hover{ background:var(--wash); border-color:var(--clay-a11y); }
.prm__sum:focus-visible{ outline:2px solid var(--clay-a11y); outline-offset:2px; }
.prm[open] .prm__sum{
  border-bottom-left-radius:0; border-bottom-right-radius:0;
  border-bottom-color:transparent; background:var(--wash);
}

/* the icon: the thing the eye lands on */
.prm__badge{
  flex:none; width:34px; height:34px; border-radius:10px;
  display:grid; place-items:center;
  background:var(--clay-soft); color:var(--clay-txt);
}
.prm__lines{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.prm__ttl{ font-size:14px; font-weight:600; color:var(--ink); line-height:1.3; }
.prm__sub{ font-size:11.5px; color:var(--t3); line-height:1.4; }
.prm__chev{
  margin-inline-start:auto; flex:none;
  display:inline-flex; color:var(--t2);
  transition:transform .22s var(--ease);
}
.prm[open] .prm__chev{ transform:rotate(180deg); }

/* the panel, hanging off the button it opened from */
.prm__body{
  padding:16px;
  background:var(--wash);
  border:1px solid var(--line-strong, var(--line));
  border-top:0;
  border-radius:0 0 14px 14px;
}
.prm__txt{
  margin:0;
  font-size:12.5px; line-height:2;          /* long Hebrew wants air */
  color:var(--t2);
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:11px;
  padding:14px 15px;
}
.prm__mark{
  background:var(--clay-soft); color:var(--clay-txt);
  border-radius:5px; padding:1px 5px; font-weight:600;
}
.prm__copy{ width:100%; margin-top:14px; }
.prm__copyic{ display:inline-flex; margin-inline-end:8px; vertical-align:-3px; }
.prm__note{
  margin:12px 2px 0; font-size:11.5px; line-height:1.75; color:var(--t3);
}


/* which screen the preview is showing — the invitation, or the sealed
   opening screen whose artwork the couple may be editing */
.ed__screen{
  display:flex; gap:6px; justify-content:center; flex-wrap:wrap;
  margin:0 0 10px; width:100%; max-width:340px;
}
.ed__screenbtn{
  padding:7px 14px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:var(--paper);
  font:inherit; font-size:12px; color:var(--t2); cursor:pointer;
  transition:background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.ed__screenbtn:hover{ background:var(--wash); color:var(--ink); }
.ed__screenbtn.is-on{
  background:var(--ink); border-color:var(--ink); color:#fff;
}

/* ============================================================
   PACKAGES WITHOUT RSVP (הזמנה מעוצבת)
   K.api.currentEvent() sets <html data-rsvp="on|off">. Anything that
   only means something when guests can reply is marked
   data-needs="rsvp"; the explanation that replaces it, "no-rsvp".
   ============================================================ */
html[data-rsvp="off"] [data-needs="rsvp"]{ display:none !important; }
html:not([data-rsvp="off"]) [data-needs="no-rsvp"]{ display:none !important; }
.pkgnote{ margin-top:16px; padding:18px; }
.pkgnote p{ margin:6px 0 14px; }

/* a category with no designs yet: the chip stays, and says so */
.chip__soon{ font-size:10.5px; padding:1px 7px; margin-inline-start:6px; border-radius:var(--r-pill);
  background:var(--wash); color:var(--t3); vertical-align:1px; }
.chip.is-on .chip__soon{ background:rgba(255,255,255,.22); color:#fff; }

/* ---- how it works, on the package page ----
   The last screen before paying, so the place a couple who knows the
   RSVP services learns this one works differently. */
.kp-how{ margin-top:32px; padding-top:28px; border-top:1px solid #e8dfd7; }
.kp-how h2{ font:500 20px/1.4 var(--f-body); margin:0 0 16px; }
.kp-how ol{ list-style:none; padding:0; margin:0; display:grid; gap:14px; counter-reset:kp; }
.kp-how li{ position:relative; padding-inline-start:40px; font-size:15px; line-height:1.7; color:#4a4440; }
.kp-how li::before{ counter-increment:kp; content:counter(kp); position:absolute; right:0; top:1px;
  width:26px; height:26px; border-radius:50%; background:#f6efe9; color:#b7705a;
  font-size:13px; font-weight:600; display:flex; align-items:center; justify-content:center; }
.kp-how li b{ color:#292624; font-weight:600; }
.kp-how__note{ margin:16px 0 0; font-size:13.5px; color:#746b65; line-height:1.75; }
@media (min-width:768px){ .kp-how ol{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:24px; } }

/* the three steps above a send button: what will happen when it is pressed */
.howto{ list-style:none; padding:0; margin:10px 0 8px; counter-reset:h; display:grid; gap:8px; }
.howto li{ position:relative; padding-inline-start:30px; font-size:13.5px; line-height:1.6; color:var(--t2); }
.howto li::before{ counter-increment:h; content:counter(h); position:absolute; right:0; top:1px;
  width:20px; height:20px; border-radius:50%; background:var(--wash); color:var(--clay-txt);
  font-size:11.5px; font-weight:600; display:flex; align-items:center; justify-content:center; }

/* the launch switch at the top of /admin/ */
.adm-sales{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:0 0 18px;
  padding:14px 16px; border-radius:14px; border:1px solid var(--line); background:var(--paper); font-size:13.5px; }
.adm-sales.is-closed{ background:#fbf3ea; border-color:#ecd9c4; }
.adm-sales.is-open{ background:#eef6ee; border-color:#cfe3cf; }
.adm-sales__dot{ width:10px; height:10px; border-radius:50%; flex:none; background:#c9a36f; }
.adm-sales.is-open .adm-sales__dot{ background:#3f9a4b; }
.adm-sales__t{ flex:1; min-width:200px; display:flex; flex-direction:column; gap:3px; }
.adm-sales__t i{ font-style:normal; color:var(--t2); line-height:1.6; }
.adm-sales .btn{ width:auto; padding:0 16px; }

/* "מה מיוחד ב־…" under the gallery */
.lovecard__l{ margin:2px 0 0; padding:0 18px 0 0; font-size:13px; color:var(--t2); line-height:1.75; }
.lovecard[hidden]{ display:none; }

/* the design's headline, above its paragraph */
.dt__hook{ font-size:18px; line-height:1.45; font-weight:600; color:var(--t1); margin:12px 0 6px; text-wrap:balance; }
.dt__hook[hidden], .dt__desc[hidden]{ display:none; }
@media (min-width:768px){ .dt__hook{ font-size:20px; } }

/* one short line on the product page: how many of the couple's photos */
.dt__photos{ margin:4px 0 14px; font-size:14px; color:var(--t2); }
.dt__photos b{ color:var(--t1); font-weight:600; }
.dt__photos[hidden]{ display:none; }

/* `hidden` has to win over a class that sets display. The Google button
   (.btn, display:flex) stayed on screen with Google sign-in switched off,
   and pressing it showed an error. */
.btn[hidden], .divider[hidden], .card[hidden]{ display:none !important; }

/* guest list: sending starts right here */
.gsendbar{ margin:14px 0 6px; }
.gsendbar[hidden]{ display:none; }
.gsendbar .btn span{ display:inline-flex; vertical-align:-3px; }
.gsendbar__t{ margin:8px 2px 0; font-size:12.5px; color:var(--t2); line-height:1.7; }
