/* Bookie design system. The whole product's CSS, in one file.
 *
 * Decided in docs/design/01-directions.md part 4 ("החלון המשותף"). Nothing here is invented: the
 * colour is measured off the logo, the type scale is Heebo's, the radius scale is generated from
 * one number, and there are exactly two elevations.
 *
 * LOAD ORDER MATTERS. base.html links a11y.css FIRST and this file SECOND, on purpose. a11y.css
 * still ships the widget's own chrome and its four palette classes written against the OLD token
 * names; this file redeclares every palette at the same specificity and wins by source order, so
 * the widget keeps working while the tokens move. The legacy aliases at the end of each palette
 * block (--muted, --line, --card, --tint, --shadow) exist for the same reason: every template
 * shipped before this file still reads them, and a rename would be a hundred silent regressions.
 *
 * No per page CSS. A rule that would live in a template's <style> block lives here as a class.
 */

/* ================================================================ 1. tokens, light */
:root{
  /* ---- ink. Every value clears 4.5:1 on surface, page, brand tint and the committed field. */
  --ink:#16264A;                  /* text primary, the wordmark navy. 14.89:1 on surface */
  --ink-2:#586274;                /* text secondary. 6.15:1 */
  --ink-3:#647087;                /* muted. 4.99:1, and 4.51:1 on the brand tint */

  /* ---- ground. Borders are alpha over ink, not named greys, so nesting stays coherent. */
  --bg:#F7F8FB;
  --surface:#FFFFFF;
  --surface-2:#F2F3F5;            /* committed time in the grid: ink at 5.5%. Never carries text */
  --border:rgba(22,38,74,.10);
  --border-strong:rgba(22,38,74,.18);

  /* ---- brand. #4A6AFB off the mark is 4.42:1 on white and fails, so the primary is that hue
     darkened to the first value that clears 4.5:1 in BOTH directions: #3D5AF1 at 5.34:1. One
     number, both jobs, no separate link blue. The base palette carries no brand hue: blue appears
     on the shared window and on the primary action, and nowhere else. */
  --brand:#3D5AF1;
  --brand-hover:#2F4FE0;
  --brand-ink:#FFFFFF;
  --brand-subtle:rgba(61,90,241,.07);
  --brand-line:rgba(61,90,241,.22);
  --accent:#5F4AF8;               /* the logo violet: preferred slot dot, cross company seam */
  --accent-subtle:rgba(95,74,248,.08);

  /* ---- semantic */
  --ok:#0F6B3C;   --ok-subtle:rgba(15,107,60,.07);
  --warn:#7A5200; --warn-subtle:rgba(122,82,0,.09);
  --bad:#B3261E;  --bad-subtle:rgba(179,38,30,.07); --bad-line:rgba(179,38,30,.30);

  /* WhatsApp keeps its own colour in every palette: the colour IS the promise of where it goes. */
  --wa:#25D366; --wa-ink:#05341A;

  /* ---- type. Heebo variable, wght 100 to 900, self hosted, Hebrew plus Latin subsets. Kept
     because it is measured best for this product: x-height 0.528em, tabular numerals by default
     at 1151/2048 with no font-feature-settings, and a continuous weight axis. */
  --font:'Heebo','Noto Sans Hebrew','Arial Hebrew',system-ui,sans-serif;

  --t-display:600 2.5rem/1.15 var(--font);      /* 40px, 32px below 768 */
  --t-h1:600 2rem/1.18 var(--font);             /* 32px, 28px below 768 */
  --t-h2:600 1.5rem/1.25 var(--font);           /* 24px */
  --t-h3:600 1.1875rem/1.35 var(--font);        /* 19px */
  --t-body-lg:400 1.1875rem/1.55 var(--font);   /* 19px */
  --t-body:400 1.0625rem/1.55 var(--font);      /* 17px, the floor */
  --t-caption:400 .9375rem/1.45 var(--font);    /* 15px */
  --t-button:500 1.125rem/1 var(--font);        /* 18px, 600 on .primary */
  --t-time:600 1.375rem/1.15 var(--font);       /* 22px, the slot pill */
  --t-time-lg:600 1.75rem/1.15 var(--font);     /* 28px, the first answer card */
  --t-gutter:400 .8125rem/1 var(--font);        /* 13px, the grid's hour ruler */

  /* ---- spacing. One four based scale, no arbitrary values. */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px;
  --s7:32px; --s8:40px; --s9:56px; --s10:72px; --s11:96px;

  /* ---- radius. One base number generates the scale. */
  --r:14px;
  --r-sm:calc(var(--r) - 8px);   /* 6px  chips, badges */
  --r-md:calc(var(--r) - 4px);   /* 10px inputs, small buttons */
  --r-lg:var(--r);               /* 14px cards, slot pills, buttons */
  --r-xl:calc(var(--r) + 6px);   /* 20px sheets, the answer card, hero panels */
  --r-pill:999px;

  /* ---- elevation. Two levels, and the second is only for things that float. */
  --e1:0 1px 2px rgba(22,38,74,.05), 0 6px 20px rgba(22,38,74,.04);
  --e2:0 2px 6px rgba(22,38,74,.08), 0 18px 44px rgba(22,38,74,.12);

  /* ---- motion. Two easings, four durations, nothing else in the system. */
  --ease:cubic-bezier(.2,.7,.3,1);
  --ease-out:cubic-bezier(.3,0,.8,.15);
  --d-fast:140ms; --d:220ms; --d-slow:320ms; --d-hero:3200ms;

  /* ---- legacy aliases. Read by every template written before this file, and by a11y.css. */
  --muted:var(--ink-3); --line:var(--border); --card:var(--surface);
  --tint:var(--brand-subtle); --tint-line:var(--brand-line); --bad-tint:var(--bad-subtle);
  --shadow:var(--e1);
}

/* ================================================================ 2. tokens, the three widget
   palettes. Dark is a CHOICE made in the accessibility widget, never prefers-color-scheme: a
   secretary whose phone flips to dark at sunset should not watch the product she is mid call with
   change colour underneath her. */
html.a11y-dark{
  --ink:#EDF1F7; --ink-2:#A3AEBE; --ink-3:#8E9BAD;
  --bg:#0E1219; --surface:#161C26; --surface-2:#252B35;
  --border:rgba(237,241,247,.12); --border-strong:rgba(237,241,247,.22);
  --brand:#93A9FF; --brand-hover:#A7B8FF; --brand-ink:#06101F;
  /* .12 rather than .16: at .16 the tint computes to #2A3349 and --ink-3 lands at 4.46:1. */
  --brand-subtle:rgba(147,169,255,.12); --brand-line:rgba(147,169,255,.34);
  --accent:#B0A0FF; --accent-subtle:rgba(176,160,255,.12);
  --ok:#57D694;   --ok-subtle:rgba(87,214,148,.12);
  --warn:#EFC257; --warn-subtle:rgba(239,194,87,.12);
  --bad:#FF9A88;  --bad-subtle:rgba(255,154,136,.12); --bad-line:rgba(255,154,136,.38);
  --wa:#25D366; --wa-ink:#05341A;
  --e1:0 1px 2px rgba(0,0,0,.45), 0 6px 20px rgba(0,0,0,.30);
  --e2:0 2px 6px rgba(0,0,0,.55), 0 18px 44px rgba(0,0,0,.45);
  --muted:var(--ink-3); --line:var(--border); --card:var(--surface);
  --tint:var(--brand-subtle); --tint-line:var(--brand-line); --bad-tint:var(--bad-subtle);
  --shadow:var(--e1);
  color-scheme:dark;
}

/* High contrast keeps every ground black and every ink white, so elevation is removed rather than
   recoloured. NO filter on html, body or any ancestor of a fixed element: a filter turns that
   element into the containing block for its fixed descendants and the sticky action bar stops
   being pinned to the viewport. */
html.a11y-contrast{
  --ink:#FFFFFF; --ink-2:#FFFFFF; --ink-3:#FFFFFF;
  --bg:#000000; --surface:#000000; --surface-2:#000000;
  --border:#FFFFFF; --border-strong:#FFFFFF;
  --brand:#FFE14D; --brand-hover:#FFE14D; --brand-ink:#000000;
  --brand-subtle:#000000; --brand-line:#FFFFFF;
  --accent:#FFE14D; --accent-subtle:#000000;
  --ok:#FFFFFF; --ok-subtle:#000000;
  --warn:#FFFFFF; --warn-subtle:#000000;
  --bad:#FFFFFF; --bad-subtle:#000000; --bad-line:#FFFFFF;
  --e1:none; --e2:none;
  --muted:var(--ink-3); --line:var(--border); --card:var(--surface);
  --tint:var(--brand-subtle); --tint-line:var(--brand-line); --bad-tint:var(--bad-subtle);
  --shadow:none;
  color-scheme:dark;
}

/* Grayscale is a palette, not a filter, for the same containing block reason. */
html.a11y-gray{
  --brand:#3D4450; --brand-hover:#2C323C; --brand-ink:#FFFFFF;
  --brand-subtle:rgba(60,66,74,.10); --brand-line:rgba(60,66,74,.28);
  --accent:#3D4450; --accent-subtle:rgba(60,66,74,.10);
  --ok:#3F3F3F; --warn:#5C5C5C; --bad:#2B2B2B;
  --ok-subtle:rgba(63,63,63,.09); --warn-subtle:rgba(92,92,92,.09);
  --bad-subtle:rgba(43,43,43,.09); --bad-line:rgba(43,43,43,.34);
  --tint:var(--brand-subtle); --tint-line:var(--brand-line); --bad-tint:var(--bad-subtle);
}

@media (prefers-reduced-motion:reduce){
  :root{ --d-fast:0ms; --d:0ms; --d-slow:0ms; --d-hero:0ms; }
}

/* ================================================================ 3. base */
*{box-sizing:border-box}
html,body{margin:0; padding:0}
/* Sizes are rem so the accessibility widget's text size control actually moves them. An absolute
   px on <body> would swallow the root font size change and the button would do nothing. */
body{
  font:var(--t-body); color:var(--ink); background:var(--bg);
  -webkit-font-smoothing:antialiased; letter-spacing:0;
}
/* Hebrew has no case, so never text-transform, and tracking is 0 everywhere. Emphasis is weight
   500 to 600 and never 700, and no Hebrew italic ships. */
h1,h2,h3,h4{letter-spacing:0; font-weight:600; margin:0 0 .4em}
h1{font:var(--t-h1)} h2{font:var(--t-h2)} h3{font:var(--t-h3)}
a{color:var(--brand)}
p{margin:0 0 var(--s3)}
hr{border:0; border-top:1px solid var(--border); margin:var(--s6) 0}

/* The numeral is a component, not a font size. Two digit runs separated by a neutral space in one
   text node swap places silently and the reader believes the wrong fact. */
.num,.time,.dayhead time{font-variant-numeric:tabular-nums; unicode-bidi:isolate; direction:ltr}
/* Latin runs inside Hebrew sentences: Google, Bookie, WhatsApp, emails, URLs. */
bdi,.ltr{unicode-bidi:isolate}
.ltr{direction:ltr; display:inline-block}

/* One focus ring for everything. The browser default disappears against a filled brand button,
   and Israeli standard 5568 asks for a visible one. */
:focus-visible{outline:3px solid var(--brand); outline-offset:2px; border-radius:4px}

.muted{color:var(--ink-3)}
.small{font:var(--t-caption)}
.big{font:var(--t-body-lg)}
.hero{font:var(--t-display); margin:0 0 .3em}
.stack{display:flex; flex-direction:column; gap:var(--s3)}
.inline{display:flex; gap:10px; flex-wrap:wrap; align-items:center}
.spread{display:flex; align-items:center; justify-content:space-between; gap:var(--s3)}
.grow{flex:1 1 auto; min-width:0}
.nowrap{white-space:nowrap}
[hidden]{display:none !important}

.skip{position:absolute; inset-inline-start:-9999px; top:8px; z-index:99;
      background:var(--surface); color:var(--ink); border:2px solid var(--brand);
      border-radius:var(--r-md); padding:12px 18px; text-decoration:none}
.skip:focus{inset-inline-start:8px}

/* The reading column. min() rather than max-width: at 768 a 760px column inside a 4px gutter is
   the ugliest state the product has, and this is the whole tablet fix. */
.wrap{width:min(760px, 100% - 48px); margin:0 auto; padding:var(--s6) 0 var(--s10)}
.wrap.wide-col{width:min(1120px, 100% - 48px)}
@media (max-width:767px){ .wrap{width:calc(100% - 32px); padding:18px 0 var(--s9)} }

/* ================================================================ 4. the shell */
/* A 64px bar on --surface with a 1px --border underline, no shadow. Six things in the bar, one
   accent. Below 768 it is 56px: one 48x48 control at the start edge, the wordmark at the end. */
.bar{display:flex; align-items:center; gap:var(--s5); height:64px; padding:0 var(--s6);
     border-bottom:1px solid var(--border); background:var(--surface)}
.bar .brand{display:flex; align-items:center; flex:0 0 auto}
.bar .brand img{display:block; height:32px; width:auto}
.navlinks{display:flex; align-items:center; gap:var(--s5)}
.navlinks a{color:var(--ink-2); text-decoration:none; font:var(--t-body);
            padding:var(--s2) 0; border-bottom:2px solid transparent}
.navlinks a:hover{color:var(--ink)}
.navlinks a[aria-current="page"]{color:var(--ink); font-weight:600; border-bottom-color:var(--brand)}
.barend{display:flex; align-items:center; gap:var(--s3); margin-inline-start:auto}
/* The compatibility lane for templates that still fill {% block barright %}. Hidden below 768,
   where the עוד sheet is the whole secondary navigation: the two links it used to hold there
   measured 44x23 px and 32x23 px, under half the minimum target height. */
.barright{display:flex; align-items:center; gap:var(--s4); font:var(--t-caption)}
.barright a{color:var(--ink-3)}
/* פגישה חדשה is not a fifth text link: it is the filled primary pill inside the bar, present on
   every screen, at 44px rather than the 52px of an in page button. */
.bar .btn.navnew{min-height:44px; padding:0 18px; font-size:1.0625rem}

/* The account menu and the עוד sheet are ONE <details>. One summary, two visual forms, so the
   anchors are real anchors in the DOM at every width and no JavaScript owns the navigation. */
.navmenu{position:relative}
.navmenu > summary{list-style:none; cursor:pointer; display:flex; align-items:center;
                   border-radius:var(--r-pill)}
.navmenu > summary::-webkit-details-marker{display:none}
.morebtn{display:none; width:48px; height:48px; align-items:center; justify-content:center;
         border-radius:var(--r-md); color:var(--ink)}
.navmenu[open] > summary .morebtn{background:var(--brand-subtle)}

/* Desktop: a dropdown anchored to the end edge. It floats, so it gets --e2. */
.menupanel{position:absolute; inset-inline-end:0; top:calc(100% + var(--s2)); z-index:60;
           min-width:260px; background:var(--surface); border:1px solid var(--border);
           border-radius:var(--r-lg); box-shadow:var(--e2); padding:var(--s2);
           animation:pop var(--d-fast) var(--ease)}
@keyframes pop{from{opacity:0; transform:translateY(-4px)} to{opacity:1; transform:none}}
.menupanel a,.menupanel button{display:flex; align-items:center; gap:10px; width:100%;
           min-height:52px; padding:0 var(--s3); border:0; background:none; color:var(--ink);
           font:var(--t-body); text-decoration:none; cursor:pointer; border-radius:var(--r-md);
           text-align:start}
.menupanel a:hover,.menupanel button:hover{background:var(--brand-subtle)}
.menupanel form{margin:0}
.menupanel hr{margin:var(--s2) var(--s3)}
.menutitle{font:var(--t-caption); color:var(--ink-3); padding:var(--s2) var(--s3) var(--s1)}
.sheet-nav{display:none}
/* The scrim only exists once the menu is open, so it is never a resting fixed layer. */
.navmenu[open] > summary::before{content:""; position:fixed; inset:0; z-index:59}

@media (max-width:767px){
  .bar{height:56px; padding:0 var(--s4); gap:var(--s3)}
  .navlinks,.bar .btn.navnew,.barright{display:none}
  .bar .brand{order:2; margin-inline-start:auto}
  .barend{order:1; margin-inline-start:0}
  .morebtn{display:flex}
  .avatar-btn{display:none}
  .sheet-nav{display:block}
  /* The עוד half sheet. Auto height, capped at 60dvh, dvh and never vh because iOS 26 moved the
     address bar to the bottom. */
  .navmenu[open] > summary::before{background:rgba(22,38,74,.32); z-index:70}
  .menupanel{position:fixed; inset-inline:0; bottom:0; top:auto; z-index:71;
             min-width:0; max-height:60dvh; overflow-y:auto;
             border-radius:var(--r-xl) var(--r-xl) 0 0; border-inline:0; border-bottom:0;
             padding:var(--s2) var(--s4) calc(var(--s4) + env(safe-area-inset-bottom));
             animation:sheetup var(--d-slow) var(--ease)}
  .menupanel::before{content:""; display:block; width:36px; height:4px; border-radius:var(--r-pill);
             background:var(--border-strong); margin:var(--s3) auto var(--s2)}
  .menupanel a,.menupanel button{min-height:56px}
}
@keyframes sheetup{from{transform:translateY(100%)} to{transform:none}}

.foot{width:min(760px, 100% - 48px); margin:0 auto; padding:0 0 var(--s7);
      display:flex; gap:var(--s4); flex-wrap:wrap; font:var(--t-caption)}
.foot a{color:var(--ink-3)}

/* ================================================================ 5. buttons */
/* 52px rather than 44px because the user is holding a telephone. Four variants and no fifth. */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:10px;
     min-height:52px; padding:0 22px; border-radius:var(--r-lg);
     border:1px solid var(--border); background:var(--surface); color:var(--ink);
     font:var(--t-button); text-decoration:none; cursor:pointer;
     transition:transform var(--d-fast) var(--ease), background-color var(--d-fast) var(--ease),
                border-color var(--d-fast) var(--ease)}
.btn:hover{border-color:var(--border-strong)}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--brand); color:var(--brand-ink); border-color:transparent;
             font-weight:600; box-shadow:var(--e1)}
.btn.primary:hover{background:var(--brand-hover); border-color:transparent}
.btn.primary:active{box-shadow:none}
.btn.secondary{background:var(--surface); color:var(--ink); border-color:var(--border)}
/* Quiet is a link that keeps a target: no border, no fill, still 52px under a thumb. */
.btn.quiet{border-color:transparent; background:none; color:var(--ink-2); padding:0 12px}
.btn.quiet:hover{background:var(--brand-subtle); color:var(--ink); border-color:transparent}
.btn.danger{color:var(--bad); border-color:var(--bad-line); background:var(--surface)}
.btn.danger:hover{background:var(--bad-subtle); border-color:var(--bad)}
.btn.danger.filled{background:var(--bad); color:#fff; border-color:transparent}
/* WhatsApp green with near black ink, 7.0:1, unchanged in every palette because the colour IS
   the promise of where the button goes. */
.btn.wa{background:var(--wa); color:var(--wa-ink); border-color:transparent; font-weight:600}
.btn.sm{min-height:44px; padding:0 16px; font-size:1.0625rem}
.btn.lg{min-height:64px; font-size:1.25rem}
.btn.wide{width:100%}
/* An action that cannot work is hidden, not disabled. The one exception is the morphing submit
   button, which stays visible so its three states are learnable. */
.btn[disabled],.btn[aria-disabled="true"]{opacity:.55; box-shadow:none; cursor:default;
     pointer-events:none}
/* The busy state: the label swaps to the busy string and the width is never animated, because a
   button that changes size under a thumb is a button that moves away from it. */
form[data-busy] .busy{margin:10px 0 0; color:var(--ink-2); font:var(--t-caption)}
.busy{margin:10px 0 0; color:var(--ink-2)}

/* ================================================================ 6. chips */
.chip{display:inline-flex; align-items:center; gap:var(--s2); min-height:36px; padding:0 14px;
      border-radius:var(--r-pill); border:1px solid var(--border); background:var(--surface);
      color:var(--ink); font:var(--t-caption); font-weight:500; white-space:nowrap;
      text-decoration:none; cursor:pointer}
.chip:hover{border-color:var(--border-strong)}
.chip.on,.chip[aria-pressed="true"]{background:var(--brand-subtle); border-color:var(--brand);
      font-weight:600}
.chip[disabled]{opacity:.55; pointer-events:none}
.chip.wait{color:var(--warn); background:var(--warn-subtle); border-color:transparent; cursor:default}
.chip.ok{color:var(--ok); background:var(--ok-subtle); border-color:transparent; cursor:default}
.chip.bad{color:var(--bad); background:var(--bad-subtle); border-color:var(--bad-line); cursor:default}
/* The cross company badge. The seam is the only place the logo violet is allowed. */
.chip.seam{color:var(--accent); background:var(--accent-subtle); border-color:transparent;
      cursor:default}
.chip bdi{overflow:hidden; text-overflow:ellipsis; max-width:18ch}

/* Shape as well as colour: about one man in twelve cannot separate green from amber, and every
   dot in this product is followed by its word anyway. */
.dot{width:12px; height:12px; border-radius:50%; display:inline-block; flex:0 0 auto;
     margin-inline-end:6px; background:var(--ink-3)}
.dot.ok{background:var(--ok)} .dot.wait{background:var(--warn)} .dot.bad{background:var(--bad)}
.dot.pref{width:6px; height:6px; background:var(--accent)}

/* ================================================================ 7. avatars */
/* A square box before the radius, always. A LEAF element: the shipped bug this replaces was
   `.who span` matching a nested span, where min-width and min-height beat width and height and a
   36px avatar computed to 112x96 and rendered as a blue ellipse. Nothing may nest inside .avatar
   except the <img>. */
.avatar{display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
        width:36px; height:36px; min-width:36px; min-height:36px; border-radius:var(--r-pill);
        background:var(--brand-subtle); color:var(--brand); font-weight:600; font-size:.9375rem;
        overflow:hidden; line-height:1; user-select:none}
.avatar img{width:100%; height:100%; object-fit:cover; display:block}
.avatar.s24{width:24px; height:24px; min-width:24px; min-height:24px; font-size:.75rem}
.avatar.s28{width:28px; height:28px; min-width:28px; min-height:28px; font-size:.8125rem}
.avatar.s32{width:32px; height:32px; min-width:32px; min-height:32px; font-size:.875rem}
.avatar.s40{width:40px; height:40px; min-width:40px; min-height:40px; font-size:1rem}
.avatar.dead{background:var(--bad-subtle); color:var(--bad)}
.cluster{display:flex; align-items:center; flex-direction:row}
.cluster .avatar{box-shadow:0 0 0 2px var(--surface)}
.cluster .avatar + .avatar{margin-inline-start:-8px}
.cluster .more{background:var(--surface-2); color:var(--ink-2)}
.avatar-btn{border:0; background:none; padding:0; cursor:pointer; display:flex}

/* ================================================================ 8. cards and rows */
.card{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
      padding:var(--s6); box-shadow:var(--e1); margin:0 0 var(--s4)}
.card > h2:first-child,.card > h3:first-child{margin-top:0}
@media (max-width:767px){ .card{padding:var(--s5)} }

.row{display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
     padding:14px 0; border-bottom:1px solid var(--border)}
.row:last-child{border-bottom:0}
.row.sel{box-shadow:inset 3px 0 0 var(--brand)}

/* A participant is a 56px full width row, not a card. Seven people are about 400px of screen
   rather than the roughly 1,000px the old cards produced. The whole row is a label wrapping a
   real checkbox, so :checked does the state with no JavaScript and a keyboard reaches every
   option. */
.person-row{position:relative; display:flex; align-items:center; gap:var(--s3);
     min-height:56px; padding:0 var(--s4); border:1px solid var(--border);
     border-radius:var(--r-lg); background:var(--surface); cursor:pointer; margin:0 0 var(--s2)}
.person-row input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0;
     cursor:pointer}
.person-row .nm{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis;
     white-space:nowrap}
.person-row .st{color:var(--ink-3); font:var(--t-caption); white-space:nowrap}
.person-row:hover{background:var(--brand-subtle)}
.person-row:has(input:checked){box-shadow:inset 0 0 0 2px var(--brand); border-color:var(--brand);
     background:var(--brand-subtle)}
.person-row:has(input:focus-visible){outline:3px solid var(--brand); outline-offset:2px}
/* A calendar Bookie cannot read must never look bookable. */
.person-row.dead{color:var(--ink-3); cursor:default; background:var(--bg)}
.person-row.dead:hover{background:var(--bg)}

/* ================================================================ 9. the availability object */
/* D1, the first answer card. The only elevated object in the main area. */
.answer{border:1px solid var(--brand-line); background:var(--brand-subtle);
        border-radius:var(--r-xl); box-shadow:var(--e1); padding:var(--s6); margin:0 0 var(--s6)}
.answer .meta{display:flex; align-items:center; gap:10px; font:var(--t-caption);
        color:var(--ink-2); margin:0 0 var(--s3)}
.answer .when{font:var(--t-time-lg); font-variant-numeric:tabular-nums; margin:0 0 var(--s1)}
.answer .all{color:var(--ink-2); margin:0 0 var(--s5)}
.answer .acts{display:flex; gap:var(--s3)}
.answer .acts .btn{min-height:56px}
.answer .acts .btn.primary{min-width:220px}
@media (max-width:767px){
  .answer{padding:var(--s5)}
  .answer .when{font-size:1.5rem}
  .answer .acts{flex-direction:column; gap:10px}
  .answer .acts .btn{width:100%}
}

/* D2, the ranked day rows. An <h2> so a screen reader can jump day by day. */
.dayhead{margin:var(--s5) 0 var(--s2); font:var(--t-h3)}
.dayrow{display:flex; align-items:center; gap:var(--s4); min-height:72px;
        border-bottom:1px solid var(--border)}
.dayrow .label{flex:0 0 132px; font-weight:600}
.dayrow .label span{color:var(--ink-2); font-weight:400}
.dayrow .pills{display:flex; flex-wrap:wrap; gap:10px; padding:var(--s3) 0}
/* A day with nothing available renders the row rather than being hidden: an absent row reads as
   a bug. One muted word, and it is תפוס rather than the copy guardrail's אין. */
.dayrow .taken{color:var(--ink-3)}
@media (max-width:767px){
  .dayrow{display:block; min-height:0; border-bottom:0; margin:0 0 var(--s5)}
  .dayrow .label{font:var(--t-h3); margin:0 0 var(--s2)}
}

/* The time pill. It carries the time and nothing else, because the day is the heading above it. */
.slot{position:relative; display:inline-flex; align-items:center; justify-content:center;
      min-height:56px; min-width:92px; padding:0 var(--s4); border:1px solid var(--border);
      border-radius:var(--r-lg); background:var(--surface); color:var(--ink);
      font:var(--t-time); font-variant-numeric:tabular-nums; cursor:pointer;
      transition:transform var(--d-fast) var(--ease)}
.slot input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer}
.slot:hover{border-color:var(--brand-line)}
.slot:active{transform:scale(.985)}
/* Selection is an inset ring, NEVER a loss of saturation. Calendly turns the slot you just chose
   grey while every unchosen one stays blue outlined, so the only item that reads as disabled is
   the one you picked. */
.slot:has(input:checked){box-shadow:inset 0 0 0 2px var(--brand); border-color:var(--brand);
      background:var(--brand-subtle); font-weight:600}
.slot:has(input:focus-visible){outline:3px solid var(--brand); outline-offset:2px}
.slot[disabled],.slot.off{opacity:.55; pointer-events:none}

/* The external page's slot row: the reader has no calendar open and no idea what day it is, so
   the day is on the first line and the time range on the second. */
.slotrow{display:block; width:100%; text-align:start; min-height:72px; padding:14px 18px;
      margin:0 0 10px; border:1px solid var(--border); border-radius:var(--r-lg);
      background:var(--surface); color:var(--ink); font:var(--t-body); cursor:pointer;
      text-decoration:none}
.slotrow:hover{border-color:var(--brand)}
.slotrow .when{display:block; font:var(--t-time); font-variant-numeric:tabular-nums;
      unicode-bidi:isolate}
/* The taken slot vanishes in place, where the thumb already is. */
.slotrow.gone{animation:collapse var(--d-slow) var(--ease) forwards}
@keyframes collapse{to{height:0; min-height:0; opacity:0; margin:0; padding:0; border-width:0}}

/* ================================================================ 10. date range, segmented */
/* Duration and range as one segmented pill track, active option a filled pill on a quiet rail. */
.choices{display:flex; flex-wrap:wrap; gap:10px; margin:0 0 var(--s2)}
.seg{display:inline-flex; gap:var(--s1); padding:var(--s1); background:var(--surface-2);
     border-radius:var(--r-pill)}
.seg .pick span{border:0; background:none; min-height:48px; border-radius:var(--r-pill)}
.seg .pick input:checked + span{background:var(--surface); box-shadow:var(--e1)}

/* .pick is the shipped label-wraps-a-real-input pattern. Kept, because :checked does the state
   with no JavaScript and a keyboard still reaches every option. */
.pick{position:relative; display:inline-flex}
.pick input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer}
.pick span{display:flex; align-items:center; justify-content:center; gap:var(--s2); min-height:56px;
     padding:0 18px; border:1px solid var(--border); border-radius:var(--r-lg);
     background:var(--surface); font-weight:500}
.pick input:checked + span{border-color:var(--brand); background:var(--brand-subtle);
     box-shadow:inset 0 0 0 2px var(--brand); font-weight:600}
.pick input:focus-visible + span{outline:3px solid var(--brand); outline-offset:2px}
.pick.dead span{border-color:var(--bad-line); color:var(--bad); background:var(--bad-subtle)}
/* The old people picker. Kept renderable while meeting_new.html still uses it; .person-row is
   what replaces it. */
.who > span{flex-direction:column; gap:var(--s1); min-height:96px; min-width:112px; padding:12px 14px}
.who .init{width:36px; height:36px; min-width:36px; min-height:36px; border-radius:var(--r-pill);
     background:var(--brand); color:var(--brand-ink); display:flex; align-items:center;
     justify-content:center; font-weight:600; overflow:hidden}
.who.dead .init{background:var(--bad); color:#fff}
.who .init img{width:100%; height:100%; object-fit:cover; display:block}

/* Date states are SHAPE rather than colour, so they survive greyscale, high contrast and 160%
   text: selectable is a filled rounded square, unselectable is a bare numeral, today has a dot. */
.monthgrid{display:grid; grid-template-columns:repeat(7,1fr); gap:var(--s1)}
.monthgrid .d{display:flex; align-items:center; justify-content:center; min-height:44px;
     border-radius:var(--r-md); font-variant-numeric:tabular-nums}
.monthgrid .d.sel{background:var(--surface-2); cursor:pointer}
.monthgrid .d.on{background:var(--brand); color:var(--brand-ink); font-weight:600}
.monthgrid .d.today{position:relative}
.monthgrid .d.today::after{content:""; position:absolute; bottom:5px; width:4px; height:4px;
     border-radius:50%; background:currentColor}

/* ================================================================ 11. inputs */
.field{margin:0 0 var(--s3)}
/* A placeholder is never a label: it disappears the moment she types and a screen reader may
   never read it. */
.field label{display:block; font:var(--t-caption); color:var(--ink-2); margin:0 0 6px}
input[type=text],input[type=email],input[type=tel],input[type=url],input[type=number],
input[type=search],select,textarea{
     width:100%; min-height:52px; padding:0 14px; font:var(--t-body); color:var(--ink);
     border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface)}
textarea{min-height:84px; padding:12px 14px; line-height:1.55}
input:hover,select:hover,textarea:hover{border-color:var(--border-strong)}
input:focus-visible,select:focus-visible,textarea:focus-visible{border-color:var(--brand)}
input[aria-invalid="true"],.field.bad input,.field.bad textarea{border-color:var(--bad)}
input[disabled],select[disabled],textarea[disabled]{background:var(--surface-2); color:var(--ink-3)}
.field-err{display:block; margin:6px 0 0; color:var(--bad); font:var(--t-caption)}

/* Search filters the rows beneath it live: no submit, no results page. It appears once the team
   passes eight members, because a search field over five rows is furniture. */
.search{position:relative; display:block}
.search input{border-radius:var(--r-pill); padding-inline-start:46px}
.search .ic{position:absolute; inset-inline-start:16px; top:50%; transform:translateY(-50%);
     color:var(--ink-3); pointer-events:none}

/* The native element, so the state is announced without ARIA of our own. Direction is fixed to
   rtl: a bar that filled from the left in a right to left page reads as emptying. */
progress.slots{-webkit-appearance:none; appearance:none; display:block; width:100%; height:10px;
     border:0; border-radius:var(--r-pill); background:var(--border); direction:rtl;
     margin:10px 0 0}
progress.slots::-webkit-progress-bar{background:var(--border); border-radius:var(--r-pill)}
progress.slots::-webkit-progress-value{background:var(--brand); border-radius:var(--r-pill)}
progress.slots::-moz-progress-bar{background:var(--brand); border-radius:var(--r-pill)}

/* ================================================================ 12. sheet and dialog */
/* One component, one breakpoint. A bottom sheet on a phone, a centred dialog from 768. Height is
   dvh and never vh, because iOS 26 put the address bar at the bottom. */
/* The scrim belongs to a MODAL sheet only. `details.sheet` is also the product's plain inline
   disclosure (the note on the booking page, פרטים (רשות) on the results page), and putting a
   full viewport scrim behind those would darken the page around a paragraph. :has() is the test
   for "does this disclosure actually open a panel". */
.sheet[open]:has(> .sheet-panel) > summary::before,.scrim{content:""; position:fixed; inset:0;
     z-index:70; background:rgba(22,38,74,.32)}
.sheet > summary{cursor:pointer; font-weight:500; min-height:52px; display:flex;
     align-items:center; gap:10px; list-style:none}
.sheet > summary::-webkit-details-marker{display:none}
/* A <summary> styled display:flex loses its disclosure marker in Chrome, which leaves the most
   useful control on the results page looking like a line of plain text. */
.sheet > summary::after{content:"\25be"; margin-inline-start:auto; color:var(--ink-3);
     transition:transform var(--d-fast) var(--ease)}
.sheet[open] > summary::after{transform:rotate(180deg)}

.sheet-panel{position:fixed; inset-inline:0; bottom:0; z-index:71; max-height:60dvh;
     overflow-y:auto; background:var(--surface); border-top:1px solid var(--border);
     border-radius:var(--r-xl) var(--r-xl) 0 0; box-shadow:var(--e2);
     padding:var(--s2) var(--s5) calc(var(--s5) + env(safe-area-inset-bottom));
     animation:sheetup var(--d-slow) var(--ease)}
.sheet-panel::before{content:""; display:block; width:36px; height:4px; border-radius:var(--r-pill);
     background:var(--border-strong); margin:var(--s3) auto var(--s4)}
.sheet-panel.tall{max-height:90dvh}
.sheet-panel h2{font:var(--t-h3); margin:0 0 var(--s4)}
@media (min-width:768px){
  .sheet-panel{position:fixed; inset:auto; top:50%; inset-inline-start:50%;
       transform:translate(50%,-50%); width:min(480px, 100% - 48px); max-height:80dvh;
       border:1px solid var(--border); border-radius:var(--r-xl);
       padding:var(--s6); animation:pop var(--d) var(--ease)}
  .sheet-panel::before{display:none}
}

/* ================================================================ 13. notices and toasts */
.notice{padding:12px 16px; border-radius:var(--r-md); background:var(--brand-subtle);
        border:1px solid var(--brand-line)}
.notice.bad{background:var(--bad-subtle); border-color:var(--bad-line)}
.notice.ok{background:var(--ok-subtle); border-color:transparent; color:var(--ok)}
.notice.wait{background:var(--warn-subtle); border-color:transparent; color:var(--warn)}

/* A single role="status" region at the bottom start corner, above the safe area. One line, never
   an action, and never a success that deserves a screen. הקישור הועתק is a toast.
   הפגישה נקבעה is never a toast. */
.toast{position:fixed; inset-inline-start:16px; bottom:calc(16px + env(safe-area-inset-bottom));
       z-index:65; max-width:calc(100% - 32px); padding:12px 18px; border-radius:var(--r-lg);
       background:var(--surface); border:1px solid var(--border); box-shadow:var(--e2);
       font:var(--t-body)}
.toast.ok{color:var(--ok)} .toast.bad{color:var(--bad)}

/* ================================================================ 14. empty and success */
/* Title, one explanatory sentence, one primary action, in that order. The sentence describes a
   future event rather than a missing object. No illustration, no poetry. */
.empty{text-align:center; padding:var(--s7) var(--s5)}
.empty .motif{display:inline-flex; align-items:center; justify-content:center; width:56px;
      height:56px; border-radius:var(--r-lg); background:var(--brand-subtle); color:var(--brand);
      margin:0 0 var(--s4)}
.empty h3{margin:0 0 var(--s2)}
.empty p{color:var(--ink-2); margin:0 0 var(--s5)}

/* Success is large and satisfying, never a small toast. */
.success{text-align:center; padding:var(--s8) var(--s5)}
.success .check{display:inline-flex; align-items:center; justify-content:center; width:64px;
      height:64px; border-radius:50%; background:var(--ok-subtle); color:var(--ok);
      margin:0 0 var(--s5); animation:pip var(--d) var(--ease)}
@keyframes pip{from{transform:scale(.8)} to{transform:none}}
.success h1{font:var(--t-display); margin:0 0 var(--s3)}
.success .line{font:var(--t-body-lg); color:var(--ink-2); margin:0 0 var(--s2)}
.success .acts{display:flex; gap:var(--s3); justify-content:center; flex-wrap:wrap;
      margin-top:var(--s6)}
@media (max-width:767px){
  .success h1{font-size:2rem}
  .success .acts{flex-direction:column}
  .success .acts .btn{width:100%}
}

/* ================================================================ 15. the sticky action bar */
/* ONE fixed layer per screen besides the accessibility widget, which owns a reserved lane at
   bottom:96px (a11y.css, body.has-sticky). A third fixed layer is a design failure. */
.sticky{position:fixed; inset-inline:0; bottom:0; z-index:5; background:var(--surface);
        border-top:1px solid var(--border); box-shadow:var(--e2);
        padding:12px 16px calc(12px + env(safe-area-inset-bottom))}
.sticky .inner{width:min(760px, 100% - 48px); margin:0 auto; display:flex; gap:10px}
.sticky .inner .btn{flex:1 1 auto}
/* The page has to end above the bar. Without this the last slot row and the footer links sit
   under it and cannot be reached on a phone. */
.sticky-spacer{height:104px}
@media (max-width:767px){ .sticky .inner{width:100%} }

/* ================================================================ 16. tables */
/* Numeric cells are dir=ltr so a two digit run never swaps sides. The container scrolls, never
   the page body. */
.table-scroll,.prt-scroll,.ctl-scroll{overflow-x:auto}
table.data,table.prt{width:100%; border-collapse:collapse}
table.data th,table.prt th{text-align:start; color:var(--ink-2); font-weight:500;
      font:var(--t-caption); padding:var(--s2) 6px; border-bottom:1px solid var(--border)}
table.data td,table.prt td{padding:12px 6px; border-bottom:1px solid var(--border)}
table.data tr:last-child td,table.prt tr:last-child td{border-bottom:0}
table.data td.n,table.prt td.n,td[dir="ltr"],th[dir="ltr"]{direction:ltr; text-align:start;
      font-variant-numeric:tabular-nums; unicode-bidi:isolate}

/* ================================================================ 17. partners */
/* Bigger than the product's own numbers: this screen is read at arm's length and the figures are
   the content, not a label on it. */
.prt-nums{display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:var(--s3);
      margin:0 0 var(--s4)}
.prt-num{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
      padding:var(--s4)}
.prt-num b{display:block; font:var(--t-h1); font-variant-numeric:tabular-nums}
.prt-num span{color:var(--ink-3); font:var(--t-caption)}
.prt-funnel{display:grid; grid-template-columns:repeat(auto-fit,minmax(110px,1fr)); gap:10px}
.prt-funnel div{text-align:center; padding:10px 6px; border:1px solid var(--border);
      border-radius:var(--r-md)}
.prt-funnel b{display:block; font:var(--t-h2); font-variant-numeric:tabular-nums}
.prt-funnel span{color:var(--ink-3); font:var(--t-caption)}
.prt-link{direction:ltr; text-align:left; unicode-bidi:isolate; word-break:break-all;
      background:var(--brand-subtle); border:1px solid var(--brand-line); border-radius:var(--r-md);
      padding:12px 14px; margin:0 0 var(--s3); font:var(--t-body)}
@media (max-width:767px){ .prt-nums{grid-template-columns:1fr 1fr} }

/* ================================================================ 18. legal pages */
/* Legal text is read slowly and often on a phone, so it gets a longer line height and a real
   measure. Excluded from the copy guardrail by path. */
.legal,.a11y-doc{font-size:1.06rem; line-height:1.8}
.legal h1,.a11y-doc h1{margin-bottom:.2em}
.legal h2,.a11y-doc h2{margin:1.8em 0 .5em; font-size:1.3rem; scroll-margin-top:80px}
.legal h3,.a11y-doc h3{margin:1.4em 0 .35em; font-size:1.05rem}
.legal p,.legal li,.a11y-doc p,.a11y-doc li{max-width:70ch}
.legal ul,.legal ol,.a11y-doc ul{padding-inline-start:1.3em; margin:.6em 0}
.legal li,.a11y-doc li{margin:.4em 0}
.legal table{width:100%; border-collapse:collapse; margin:1.1em 0; font-size:.95rem}
.legal th,.legal td{border:1px solid var(--border); padding:9px 11px; text-align:start;
      vertical-align:top}
.legal th{background:var(--brand-subtle); font-weight:600}
/* A scope string is a URL. Inside Hebrew it must be isolated or the slashes jump to the wrong end
   of the line and the reviewer reads a different string than the one we request. */
.legal code{direction:ltr; unicode-bidi:isolate; font-size:.92rem; word-break:break-all;
      background:var(--brand-subtle); padding:2px 6px; border-radius:var(--r-sm)}
/* Every entry already carries its own number in the text, so the list must not add a second one.
   "1. 1. ניתוק היומן" shipped on the live delete page. */
.toc ol{margin:0; padding:0; list-style:none}
.toc li{margin:.2em 0}
.toc a{text-decoration:none}
/* Deliberately loud. An unresolved placeholder must be impossible to miss on the live page. */
.review{background:var(--warn-subtle); border:1px solid var(--warn); padding:2px 7px;
      border-radius:var(--r-sm); font-weight:600; color:var(--ink)}

/* ================================================================ 19. Bookie Control */
/* Denser, LTR, read by engineers, and it may go below 15px. The band says INTERNAL and it never
   leaks into a customer surface. control.css owns the rest. */
.internal{background:var(--warn-subtle); color:var(--warn); border-bottom:1px solid var(--warn);
      font:var(--t-caption); font-weight:600; text-align:center; padding:6px 12px;
      letter-spacing:0}

/* ================================================================ 20. icons */
.ic{width:24px; height:24px; flex:0 0 auto; display:inline-block; vertical-align:-.25em;
    color:currentColor; fill:none}
.ic.s20{width:20px; height:20px}
.ic.s16{width:16px; height:16px}
/* One glyph, rotated by CSS for all four directions. */
.ic.r90{transform:rotate(90deg)} .ic.r180{transform:rotate(180deg)} .ic.r270{transform:rotate(270deg)}

/* ================================================================ 21. the design gallery */
/* Dev only, served by routes_design.py behind config.ENV == "dev". */
.gal{margin:0 0 var(--s9)}
.gal > h2{border-bottom:1px solid var(--border); padding-bottom:var(--s2); margin-bottom:var(--s5)}
.gal .strip{display:flex; flex-wrap:wrap; gap:var(--s3); align-items:center; margin:0 0 var(--s4)}
.swatch{width:88px}
.swatch i{display:block; height:48px; border-radius:var(--r-md); border:1px solid var(--border)}
.swatch b{display:block; font:var(--t-caption); font-weight:400; color:var(--ink-2);
      margin-top:var(--s1)}

/* ================================================================ 22. the hero-viz block
   The public homepage and onboarding. Appended, nothing above this line was touched.

   Everything a template would otherwise have put in a <style> block lives here as a class, per
   the file header rule. Two prefixes: `.hero-viz` and its `.hv-*` parts for the hero
   visualisation, `.lp-*` for the homepage's section composition, `.ob-*` for onboarding.

   The visualisation is drawn in its END state. Motion is an addition on top, so a phone, a
   reduced-motion reader and a browser that never runs the keyframes all get the answer rather
   than an empty frame. That is also why the media query below is `no-preference` and `min-width`
   rather than a `reduce` override: the default IS the static composed image. */

/* Public home puts its sections at max 1120 (design matrix 6.1), which the reading column at 760
   cannot hold a two column hero inside. One rule, scoped to the page, so base.html stays shared. */
body.lp .wrap{width:min(1120px, 100% - 48px)}
body.ob .wrap{width:min(480px, 100% - 32px)}

/* ---------------------------------------------------------------- section rhythm */
.lp-sec{padding:var(--s10) 0; border-top:1px solid var(--border)}
.lp-sec > h2{font:var(--t-h1); margin:0 0 var(--s3); max-width:24ch}
.lp-lead{font:var(--t-body-lg); color:var(--ink-2); max-width:62ch; margin:0 0 var(--s6)}
.lp-note{font:var(--t-body-lg); color:var(--ink-2); max-width:62ch; margin:var(--s6) 0 0}
.lp-acts{display:flex; flex-wrap:wrap; gap:var(--s3); margin:var(--s6) 0 0}
@media (max-width:767px){
  .lp-sec{padding:var(--s8) 0}
  .lp-sec > h2{font:var(--t-h2)}
  .lp-acts .btn{width:100%}
}

/* ---------------------------------------------------------------- the hero
   Two columns at 1024 and above: copy 560 at the start edge, visualisation 520 at the end edge.
   RTL resolves the start edge to the right on its own, so there is no mirrored rule here.
   The DOM order is title, visualisation, copy, which is the mobile order the brief fixes; the
   grid placement below is what pulls the visualisation beside the text on a desktop. */
.lp-hero{display:grid; gap:var(--s6) var(--s8); align-items:start; padding:var(--s9) 0 var(--s10)}
.lp-hero h1{font:var(--t-display); margin:0}
.lp-hero .lp-sub{font:var(--t-body-lg); color:var(--ink-2); max-width:52ch; margin:var(--s4) 0 var(--s6)}
.lp-cta{display:flex; flex-direction:column; gap:var(--s3); align-items:flex-start; max-width:420px}
.lp-cta .btn{min-height:56px}
.lp-cta p{margin:0}
.lp-fine{font:var(--t-caption); color:var(--ink-3)}
/* The secondary door is a link, and a link is still a target: 22px of text is half the minimum. */
.lp-signin{display:inline-flex; align-items:center; min-height:44px; padding-inline:var(--s2)}
/* The privacy answer never moves below the fold: it is the largest drop-off in this category. */
.lp-priv{font:var(--t-caption); color:var(--ink-2); max-width:52ch}
@media (min-width:1024px){
  .lp-hero{grid-template-columns:minmax(0,560px) minmax(0,520px)}
  /* No align-self on either text row: start on the grid is what makes the visualisation and
     the headline share one top edge. Centring the text block against a taller visualisation is
     what pushed the two columns apart. */
  .lp-hero h1{grid-column:1; grid-row:1}
  .lp-hero .lp-hero-copy{grid-column:1; grid-row:2}
  .lp-hero .hero-viz{grid-column:2; grid-row:1 / span 2}
}
@media (max-width:1023px){
  .lp-hero .hero-viz{width:min(640px,100%); margin-inline:auto}
}
@media (max-width:767px){
  .lp-hero{padding:var(--s6) 0 var(--s8); gap:var(--s5)}
  .lp-hero h1{font:var(--t-h1)}
  .lp-cta{max-width:none; align-items:stretch}
  .lp-cta .btn{width:100%}
}

/* ---------------------------------------------------------------- the hero visualisation
   Three day timelines, busy time in --surface-2, and the one window all three share lit in
   --brand. Inline SVG, no canvas and no library, and the captions are i18n strings rather than
   text baked into an image. */
.hero-viz{margin:0; display:flex; flex-direction:column; gap:var(--s4);
          background:var(--surface); border:1px solid var(--border);
          border-radius:var(--r-xl); box-shadow:var(--e1); padding:var(--s6)}
.hero-viz svg{display:block; width:100%; height:auto}
.hv-track{fill:var(--surface); stroke:var(--border)}
.hv-busy{fill:var(--surface-2)}
.hv-band{fill:var(--brand); opacity:.10}
.hv-win{fill:var(--brand)}
.hv-name{fill:var(--ink-2); font-family:var(--font); font-size:15px; font-weight:500}
/* The first answer card, in HTML rather than SVG text: a Hebrew day beside a 24 hour time is a
   bidi run, and SVG gives it no isolate. */
.hv-card{margin:0; border:1px solid var(--brand-line); background:var(--brand-subtle);
         border-radius:var(--r-lg); padding:var(--s4) var(--s5)}
.hv-card .when{display:block; font:var(--t-time); margin:0 0 2px}
.hv-card .all{display:block; font:var(--t-caption); color:var(--ink-2)}
.hv-who{font:var(--t-caption); color:var(--ink-3); margin:0}

/* Motion. One --d-hero loop in four beats: the lanes arrive, the busy blocks punch through, the
   shared window fills, the card sets, and the end state is held for the rest of the loop. Desktop
   only and no-preference only, because below 768 the page is often the first thing loaded on
   cellular and scroll-adjacent motion there is banned outright (directions part 7). */
@media (min-width:768px) and (prefers-reduced-motion:no-preference){
  .hero-viz .hv-lane{animation:hv-lane var(--d-hero) var(--ease) infinite both}
  .hero-viz .hv-lane:nth-of-type(2){animation-delay:120ms}
  .hero-viz .hv-lane:nth-of-type(3){animation-delay:240ms}
  .hero-viz .hv-busy{animation:hv-punch var(--d-hero) var(--ease) infinite both}
  .hero-viz .hv-busy:nth-child(2){animation-delay:60ms}
  .hero-viz .hv-busy:nth-child(3){animation-delay:120ms}
  .hero-viz .hv-band,.hero-viz .hv-win{transform-box:fill-box; transform-origin:center;
        animation:hv-open var(--d-hero) var(--ease) infinite both}
  .hero-viz .hv-card{animation:hv-set var(--d-hero) var(--ease) infinite both}
}
@keyframes hv-lane{
  0%{opacity:0; transform:translateX(20px)}
  10%,100%{opacity:1; transform:none}
}
@keyframes hv-punch{ 0%,10%{opacity:0} 20%,100%{opacity:1} }
@keyframes hv-open{
  0%,22%{opacity:0; transform:scaleX(.2)}
  32%,100%{opacity:1; transform:none}
}
/* .hv-band carries its own opacity, so its lit state is the token value rather than 1. */
@keyframes hv-set{
  0%,34%{opacity:0; transform:translateY(6px)}
  42%,100%{opacity:1; transform:none}
}
@media (min-width:768px) and (prefers-reduced-motion:no-preference){
  .hero-viz .hv-band{animation-name:hv-open-band}
}
@keyframes hv-open-band{
  0%,22%{opacity:0; transform:scaleX(.2)}
  32%,100%{opacity:.10; transform:none}
}

/* ---------------------------------------------------------------- how it works, onboarding
   Numbered cards, one line of body each, drawn motif rather than a screenshot. */
.lp-steps{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s4); margin:0}
.lp-steps .card{margin:0}
.lp-steps .n{display:inline-flex; align-items:center; justify-content:center;
             width:36px; height:36px; border-radius:var(--r-pill);
             background:var(--brand-subtle); color:var(--brand); font-variant-numeric:tabular-nums;
             font-weight:600; margin:0 0 var(--s3)}
.lp-steps h3{margin:0 0 var(--s2)}
.lp-steps p{margin:0; color:var(--ink-2); font:var(--t-caption)}
@media (max-width:1023px){ .lp-steps{grid-template-columns:1fr 1fr} }
@media (max-width:600px){ .lp-steps{grid-template-columns:1fr} }

/* A two column section: words at the start edge, the drawn thing at the end edge. */
.lp-split{display:grid; gap:var(--s8); align-items:center}
@media (min-width:1024px){ .lp-split{grid-template-columns:minmax(0,1fr) minmax(0,420px)} }

/* ---------------------------------------------------------------- the phone frame */
.lp-phone{width:min(280px,100%); margin-inline:auto; background:var(--surface);
          border:9px solid var(--ink); border-radius:34px; box-shadow:var(--e2);
          padding:var(--s5) var(--s4); display:flex; flex-direction:column; gap:10px}
.lp-phone h3{font:var(--t-caption); color:var(--ink-3); margin:0}
.lp-phone .booked{display:flex; align-items:center; gap:10px; padding:var(--s4);
                  border-radius:var(--r-lg); background:var(--brand-subtle);
                  border:1px solid var(--brand-line); font:var(--t-time); margin:0}
.lp-slot{display:flex; align-items:center; justify-content:space-between; gap:10px;
         min-height:56px; padding:10px 14px; border:1px solid var(--border);
         border-radius:var(--r-lg); background:var(--surface); font-weight:500}
.lp-slot .time{font:var(--t-time)}
/* The taken slot leaves the list by itself, and the two below it close the gap. The one piece of
   motion this section is allowed, and it is the promise being shown rather than claimed. */
@media (min-width:768px) and (prefers-reduced-motion:no-preference){
  .lp-slot.gone{animation:lp-gone var(--d-hero) var(--ease) infinite both}
}
@keyframes lp-gone{
  0%,40%{opacity:1; max-height:56px; margin-bottom:0}
  55%,90%{opacity:0; max-height:0; min-height:0; margin-bottom:-10px; padding-block:0; border-width:0}
  100%{opacity:1; max-height:56px; margin-bottom:0}
}

/* ---------------------------------------------------------------- the seam
   Two companies, a rule between them, and exactly one window crossing it. Vertical rule on a
   desktop, horizontal on a phone, which is the same rotation the product's own cross company
   screen makes at 768. */
.lp-seam{display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:var(--s4);
         padding:var(--s6); background:var(--surface); border:1px solid var(--border);
         border-radius:var(--r-xl); box-shadow:var(--e1)}
.lp-seam .side{text-align:center}
.lp-seam .side b{display:block; font-size:1.0625rem}
.lp-seam .side span{display:block; font:var(--t-caption); color:var(--ink-3); margin-top:2px}
.lp-seam .mid{display:flex; flex-direction:column; align-items:center; gap:var(--s2);
              color:var(--accent); font-weight:600}
.lp-seam .mid::before,.lp-seam .mid::after{content:""; display:block; width:1px; height:22px;
              background:var(--accent); opacity:.4}
.lp-seam-out{margin:var(--s5) 0 0; display:flex; flex-wrap:wrap; gap:var(--s3)}
/* The result and the badge are full sentences, not a name that has to stay one line, so they opt
   out of the chip's 18ch ellipsis. */
.lp-seam-out .chip{height:auto; padding-block:6px}
.lp-seam-out .chip bdi{max-width:none; overflow:visible; white-space:normal}
@media (max-width:600px){
  .lp-seam{grid-template-columns:1fr; gap:var(--s3)}
  .lp-seam .mid::before,.lp-seam .mid::after{width:22px; height:1px}
}

/* ---------------------------------------------------------------- pricing
   Two cards at display size, one price each, no comparison table and no tier badge. */
.lp-prices{display:grid; grid-template-columns:1fr 1fr; gap:var(--s4); max-width:760px}
.lp-price{display:block; text-decoration:none; color:inherit; margin:0}
.lp-price:hover{border-color:var(--brand-line)}
.lp-price .amount{display:block; font:var(--t-h2); margin:0 0 var(--s1)}
.lp-price .gross{display:block; font:var(--t-caption); color:var(--ink-3); margin:0 0 var(--s4)}
.lp-price .note{display:block; font:var(--t-caption); color:var(--ink-2); margin:0 0 var(--s3)}
@media (max-width:600px){ .lp-prices{grid-template-columns:1fr} }

/* ---------------------------------------------------------------- the final CTA */
.lp-final{text-align:center; padding:var(--s10) 0 var(--s8)}
.lp-final h2{font:var(--t-display); margin:0 0 var(--s3)}
.lp-final p{color:var(--ink-2); margin:0 auto var(--s6); max-width:52ch}
.lp-final .btn{min-height:56px; min-width:280px}
@media (max-width:767px){
  .lp-final h2{font:var(--t-h1)}
  .lp-final .btn{width:100%; min-width:0}
}

/* ---------------------------------------------------------------- the mobile sticky CTA
   position:sticky rather than the component's position:fixed, on purpose: a sticky element only
   reaches the viewport edge once its place in the flow does, so the bar appears exactly when the
   hero has scrolled out and it needs no scroll listener and no scroll driven animation, which
   part 7 bans below 768. It stays in flow, so it needs no .sticky-spacer either. */
body.lp .sticky{position:sticky; bottom:0; margin:var(--s6) 0 0; box-shadow:var(--e2)}
body.lp .sticky .inner{width:100%}
@media (min-width:768px){ body.lp .sticky{display:none} }

/* ---------------------------------------------------------------- onboarding
   One question, one full width button, and a strip that says where she is. Chrome free: the four
   step strip is the only navigation the screen needs. */
.ob-card{margin-top:var(--s8)}
.ob-brand{display:block; margin:var(--s6) auto 0; height:32px; width:auto}
.ob-strip{display:flex; align-items:flex-start; gap:var(--s2); margin:var(--s7) 0 0; padding:0;
          list-style:none}
.ob-strip li{flex:1 1 0; text-align:center; font:var(--t-caption); color:var(--ink-3);
             display:flex; flex-direction:column; align-items:center; gap:6px}
.ob-strip .mark{display:flex; align-items:center; justify-content:center; width:28px; height:28px;
                border-radius:var(--r-pill); border:1px solid var(--border);
                background:var(--surface); font-variant-numeric:tabular-nums}
.ob-strip .done{color:var(--ink-2)}
.ob-strip .done .mark{background:var(--brand); border-color:transparent; color:var(--brand-ink)}
.ob-strip .now{color:var(--ink); font-weight:600}
.ob-strip .now .mark{border-color:var(--brand); color:var(--brand)}
.ob-rename{margin:var(--s5) 0 0}
.ob-rename > summary{cursor:pointer; color:var(--ink-2); font:var(--t-caption); list-style:none;
                     min-height:44px; display:flex; align-items:center}
.ob-rename > summary::-webkit-details-marker{display:none}
.ob-rename > summary:hover{color:var(--ink)}

/* ================================================================ 22. the overlap motif */
/* Three calendars sliding into one shared window: the brief's visual idea, drawn once and used
   for both things the results area has to say. At rest it is the state before any search, beside
   the line that says what will happen. On submit it animates for exactly as long as Google takes
   and not one moment longer, because freeBusy is a real round trip and the motion exists to say
   so, never to decorate a wait. */
.viz-align{display:grid; gap:var(--s2); padding:var(--s5); margin:var(--s6) 0 var(--s3);
      border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface)}
.viz-align i,.viz-align b{display:block; height:14px; border-radius:var(--r-sm);
      background:var(--surface-2)}
/* The shared window is the only saturated shape in the motif, which is the whole argument. */
.viz-align b{background:var(--brand); opacity:.28; width:38%; margin-inline-start:31%}
@media (prefers-reduced-motion:no-preference){
  .viz-align.on i{animation:vizslide 1.2s var(--ease) infinite alternate}
  .viz-align.on i:nth-child(2){animation-delay:80ms}
  .viz-align.on i:nth-child(3){animation-delay:160ms}
  .viz-align.on b{animation:vizfill 1.2s var(--ease) infinite alternate}
  /* D2 pills settle in on arrival, staggered and capped, so a four slot day reads as a ripple
     rather than a wave. The list was just computed and the motion says that. */
  .pills .slot{animation:settle var(--d) var(--ease) backwards}
  .pills .slot:nth-child(2){animation-delay:40ms}
  .pills .slot:nth-child(3){animation-delay:80ms}
  .pills .slot:nth-child(4){animation-delay:120ms}
}
@keyframes vizslide{from{transform:translateX(-9%)} to{transform:none}}
@keyframes vizfill{from{opacity:.28} to{opacity:1}}
@keyframes settle{from{opacity:0; transform:translateY(6px)}}

@media (max-width:767px){
  /* Four durations and three ranges do not fit one 358px rail, and an inline-flex rail clips what
     does not fit rather than showing it. The rail wraps on a phone: the options are the point and
     the single line is not. Measured at 390, where 90 דקות was cut off by the viewport edge. */
  .seg{display:flex; flex-wrap:wrap; width:100%}
  .seg .pick{flex:1 1 auto}
  .seg .pick span{padding:0 10px; white-space:nowrap}
}

/* D3, the punched week grid, offered from 768 up and nowhere below it. Five columns across 358px
   is 64px per column, and a window drawn 64 wide with no label is not information. */
.weekview{display:none}
@media (min-width:768px){
  .weekview{display:block; margin:0 0 var(--s5)}
  .weekview > summary{list-style:none; cursor:pointer; display:inline-flex; margin:0 0 var(--s3)}
  .weekview > summary::-webkit-details-marker{display:none}
  /* Committed time is the field, the free windows are punched out of it, and the chosen one is
     the only brand shape on the grid. A busy block never says whose it is. */
  .weekview .monthgrid .d{background:var(--surface); border:1px solid var(--border)}
  .weekview .monthgrid .d.sel{background:var(--surface-2); border-color:transparent}
  .weekview .monthgrid .d.on{background:var(--brand); border-color:transparent}
}
