/* ============================================================
   DOOK — layout & components.
   ONE system that adapts: phone and tablet · RTL and LTR ·
   light and dark · installed and in a tab. Never a second design.

   Built from the approved component sheet (board 5a) and the craft
   rules in the handoff README. Logical properties throughout, so
   Arabic mirrors without a single RTL override of its own.
   ============================================================ */

*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}

/* --- the shell must FEEL like an app, not a page (owner, 2026-08-23) ---
   Three phone behaviours give the web away: the document rubber-banding,
   the browser bar collapsing and re-expanding as you scroll, and the
   300ms double-tap wait. The document is therefore pinned solid — ONLY
   .body scrolls, inside — and every control opts out of double-tap zoom.
   The last of the web chrome disappears with "Add to Home Screen":
   the manifest is standalone, and installed there is no bar at all. */
html{height:100%;overflow:hidden;overscroll-behavior:none;touch-action:pan-x pan-y}
body{
  position:fixed;inset:0;width:100%;height:100%;overflow:hidden;
  overscroll-behavior:none;touch-action:pan-x pan-y;
  background:var(--bg); color:var(--text);
  font-family:var(--font); font-size:var(--t-body); line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
button{font-family:inherit;color:inherit}
button,[data-act],input,a{touch-action:manipulation}

/* iOS paints autofilled fields its own yellow, straight through the dark
   theme. Repainted with the card's own ground - the inset-shadow trick is
   the only override WebKit honours. */
input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px var(--card) inset;
  -webkit-text-fill-color:var(--text);caret-color:var(--text);
  transition:background-color 999999s ease-in-out 0s;
}

/* --- shell --------------------------------------------------- */
.app{
  height:100dvh; display:flex; flex-direction:column;
  max-width:26rem; margin-inline:auto; position:relative;
  padding-top:env(safe-area-inset-top); padding-bottom:env(safe-area-inset-bottom);
}
/* tablet: the same design with more air around it — not a new layout */
@media (min-width:48rem){
  body{display:flex;align-items:center;justify-content:center}
  .app{
    height:min(100dvh,54rem); max-width:25rem;
    border:1px solid var(--card-line); border-radius:30px; overflow:hidden;
    box-shadow:0 24px 60px rgba(0,0,0,.28);
  }
}

/* --- header: transparent, centred bilingual logo -------------- */
.head{
  flex:none; height:64px; display:flex; align-items:center; justify-content:center;
  position:relative; padding-inline:20px;
}
.logo{
  height:42px; width:118px; background:var(--logo) center/contain no-repeat;
  display:block; flex:none;
}
/* The word is small; the box under it is not. A language switch is the one
   control a person hunts for one-handed, so it gets the same target as the
   back arrow — and the same inset, so the word itself barely moves. */
.head__lang{
  position:absolute; inset-inline-end:12px; background:none; border:0; cursor:pointer;
  font-size:var(--t-cap); font-weight:600; color:var(--muted);
  min-width:var(--tap); min-height:var(--tap); padding:0 8px;
  display:flex; align-items:center; justify-content:center;
}
.head__back{
  position:absolute; inset-inline-start:12px; width:var(--tap); height:var(--tap);
  display:flex; align-items:center; justify-content:center;
  background:var(--card); border:1px solid var(--card-line); border-radius:50%;
  cursor:pointer; color:var(--text);
}
:root[dir="ltr"] .head__back svg{ transform:scaleX(-1) }

/* --- page regions -------------------------------------------- */
.body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:36px var(--gutter) 24px}
.body--center{display:flex;flex-direction:column;justify-content:center;padding-top:0}
.body::-webkit-scrollbar{width:0}
.foot{flex:none;padding:16px var(--gutter) 40px;display:flex;flex-direction:column;gap:10px}

/* --- type ---------------------------------------------------- */
.title{font-size:var(--t-title);font-weight:800;line-height:1.25;letter-spacing:-.01em}
.sub{font-size:var(--t-body);color:var(--muted);line-height:1.7}
.cap{font-size:var(--t-cap);color:var(--muted);line-height:1.6}
.min{font-size:var(--t-min);color:var(--muted);line-height:1.6}
.strong{font-weight:700;color:var(--text)}
.center{text-align:center}

/* Latin figures in both languages: money is read, compared and disputed */
.fig{font-family:var(--figures);font-variant-numeric:tabular-nums;
  unicode-bidi:plaintext;white-space:nowrap}

/* ONE hero number per screen */
.hero{display:flex;align-items:baseline;gap:10px;margin-top:22px}
.hero__n{font-family:var(--figures);font-weight:800;font-size:var(--t-hero);line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;unicode-bidi:plaintext}
.hero__n--sm{font-size:var(--t-hero-sm)}
.hero__unit{font-size:19px;font-weight:600;color:var(--muted)}
.hero__lead{font-size:17px;font-weight:600}
@media (max-width:22.5rem){ .hero__n{font-size:var(--t-hero-sm)} }

/* --- the closed card: ONE per group, never stacked greys ------ */
.card{
  background:var(--card); border:1px solid var(--card-line);
  border-radius:var(--r-card); padding:4px 18px;
}
.card + .card{margin-top:12px}
.card__row{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  min-height:var(--row);
}
.card__row + .card__row{border-top:1px solid var(--hair)}
.card__head{min-height:46px;border-bottom:1px solid var(--hair)}
.card__label{font-size:var(--t-body);color:var(--muted)}
.card__title{font-size:var(--t-cardtitle);font-weight:600;color:var(--text)}
.card__value{font-family:var(--figures);font-weight:600;font-size:16px;
  font-variant-numeric:tabular-nums;unicode-bidi:plaintext;white-space:nowrap}
.card--plain{background:none;border:0;padding:0}          /* hairline group, no box */
.card--plain .card__row{padding-inline:0}

/* a bare group of rows on the background, divided by hairlines */
.rows{margin-top:var(--section)}
.rows__row{display:flex;align-items:center;justify-content:space-between;gap:12px;
  min-height:var(--row)}
.rows__row + .rows__row{border-top:1px solid var(--hair)}

/* --- badges: a 7px dot and a coloured word. No borders. ------- */
.badge{display:inline-flex;align-items:center;gap:8px;font-size:var(--t-cap);font-weight:600}
.badge__dot{width:7px;height:7px;border-radius:50%;flex:none}
.badge--ok    .badge__dot{background:var(--ok)}      .badge--ok{color:var(--ok-ink)}
.badge--mine  .badge__dot{background:var(--mine);box-shadow:0 0 8px rgba(141,95,255,.7)}
.badge--mine{color:var(--mine-ink)}
.badge--idle  .badge__dot{background:var(--idle)}    .badge--idle{color:var(--idle-ink)}
.badge--bad   .badge__dot{background:var(--bad)}     .badge--bad{color:var(--bad-ink)}

/* --- buttons -------------------------------------------------- */
/* The chamfer is the signature of the primary action, and of nothing else. */
.btn{
  height:var(--cta);width:100%;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:8px;
  background:var(--yellow);color:var(--on-yellow);
  font-weight:700;font-size:17px;line-height:1;
  clip-path:polygon(var(--chamfer) 0, calc(100% - var(--chamfer)) 0, 100% var(--chamfer),
    100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%, var(--chamfer) 100%,
    0 calc(100% - var(--chamfer)), 0 var(--chamfer));
  transition:background .12s;
}
.btn:active{background:var(--yellow-press)}
.btn[disabled]{background:var(--yellow-off);opacity:.4;cursor:not-allowed}
.btn--2{
  height:var(--cta);width:100%;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:var(--secondary);color:var(--text);border-radius:var(--r-btn);
  font-weight:700;font-size:16px;clip-path:none;
}
.btn--2:active{background:var(--secondary-press)}
.btn--2[disabled]{color:var(--muted);cursor:not-allowed}
.btn--quiet{
  height:var(--tap);width:100%;background:none;border:0;cursor:pointer;
  color:var(--muted);font-weight:600;font-size:var(--t-body);
}
.btn--quiet[disabled]{opacity:.5;cursor:not-allowed}
/* A text button still has to be hit. The word keeps its own size; the box
   under it grows downward so the banner's rhythm does not shift. */
.link{background:none;border:0;padding:0;cursor:pointer;font:inherit;
  color:var(--ok-ink);font-weight:600;
  min-height:var(--tap); display:inline-flex; align-items:center}

/* --- fields ---------------------------------------------------- */
.field{
  height:var(--cta);width:100%;background:var(--card);
  border:1.5px solid var(--card-line);border-radius:var(--r-field);
  padding-inline:16px;font-family:inherit;font-size:17px;font-weight:600;
  color:var(--text);outline:none;
}
.field::placeholder{color:var(--muted);font-weight:400}
.field:focus{border-color:var(--ok)}
.field--bad{border-color:var(--bad)}

/* the code: four boxes, and the row stays LTR even in Arabic —
   it must match the SMS the phone is reading from */
.otp{display:flex;gap:12px;direction:ltr;justify-content:center;margin-top:26px}
.otp__box{
  width:64px;height:4.5rem;background:var(--card);
  border:1.5px solid var(--card-line);border-radius:var(--r-field);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--figures);font-weight:800;font-size:30px;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--text);
}
.otp__box--on{border-color:var(--ok)}
.otp__box--bad{border-color:var(--bad)}
.otp__input{position:absolute;opacity:0;pointer-events:none;inset-block-start:0}
@media (max-width:22.5rem){ .otp{gap:9px} .otp__box{width:56px;height:4rem;font-size:26px} }

/* --- banners --------------------------------------------------- */
.banner{border-radius:var(--r-card);padding:14px 16px;margin-top:12px}
.banner__title{font-size:var(--t-cardtitle);font-weight:700;margin-bottom:6px}
.banner__body{font-size:var(--t-cap);line-height:1.65}
.banner--amber{background:var(--amber-surf);border:1px solid var(--amber-line)}
.banner--amber .banner__title,.banner--amber .banner__body{color:var(--amber-ink)}
.banner--red{background:var(--bad-surf);border:1px solid var(--bad-line)}
.banner--red .banner__title,.banner--red .banner__body{color:var(--bad-ink)}
.banner--mine{background:var(--mine-surf);border:1px solid var(--mine)}
.banner--mine .banner__title{color:var(--mine-ink)}
.banner--ok{background:var(--ok-surf);border:1px solid var(--ok)}
.banner--ok .banner__title{color:var(--ok-ink)}
.banner--quiet{background:var(--card);border:1px solid var(--card-line)}
.banner--quiet .banner__body{color:var(--muted)}

/* the debt statement card carries a violet edge, never a red one */
.edge-mine{border-inline-end:2px solid var(--mine)}

/* offline: last known data stays, and says so. Never a blank screen. */
.offline{
  flex:none;margin:6px var(--gutter) 0;background:var(--idle-surf);
  border:1px solid var(--idle-line);border-radius:var(--r-banner);
  padding:10px 14px;display:flex;align-items:center;gap:8px;
  font-size:12.5px;font-weight:600;color:var(--muted);
}

/* --- bottom sheet: depth by shadow, not by border -------------- */
.scrim{position:absolute;inset:0;background:var(--scrim);z-index:40;
  display:flex;align-items:flex-end;animation:fade .2s ease-out}
.sheet{
  width:100%;background:var(--sheet);border:1px solid var(--sheet-line);
  border-radius:var(--r-sheet) var(--r-sheet) 0 0;box-shadow:var(--sheet-shadow);
  padding:14px var(--gutter) 40px;display:flex;flex-direction:column;gap:16px;
  animation:rise .26s cubic-bezier(.2,.8,.2,1);
}
.sheet__grab{width:36px;height:4px;border-radius:2px;background:var(--grabber);align-self:center}
.sheet__title{font-size:20px;font-weight:800;line-height:1.3}
@keyframes rise{from{transform:translateY(14%)}to{transform:none}}
@keyframes fade{from{opacity:0}to{opacity:1}}

/* acceptance marks — a row of names, not logos we have no licence for */
.marks{display:flex;flex-wrap:wrap;gap:8px;justify-content:center}
.mark{border:1px solid var(--card-line);border-radius:999px;padding:7px 14px;
  font-size:12.5px;font-weight:600;color:var(--muted);white-space:nowrap}

/* --- empty / error states -------------------------------------- */
.state{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:10px;padding-block:56px}
.state__mark{width:64px;height:64px;display:flex;align-items:center;justify-content:center;
  margin-bottom:6px}
.state__title{font-size:20px;font-weight:800}

/* the octagon: the shape the brand already owns (its icon) */
.oct{clip-path:polygon(29% 0,71% 0,100% 29%,100% 71%,71% 100%,29% 100%,0 71%,0 29%)}

/* Heard, never seen. Not display:none — that is not announced either. */
.sr-only{
  position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;border:0;padding:0;margin:-1px;
}

/* --- the scan overlay: a viewfinder, outside #app ----------------
   Imperative DOM on purpose: #app is rebuilt whole on every render and
   a rebuilt <video> is a dead camera. Lives beside #say, managed only
   by actions.js. */
#scan{position:fixed;inset:0;z-index:130;background:#000}
#scan video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
#scan .scan__frame{
  position:absolute;inset-inline:16%;inset-block:26% 34%;
  border:3px solid rgba(255,214,77,.92);border-radius:18px;
  box-shadow:0 0 0 100vmax rgba(0,0,0,.45);
}
#scan .scan__hint{
  position:absolute;inset-inline:0;text-align:center;color:#F3F3F3;
  inset-block-end:calc(env(safe-area-inset-bottom) + 104px);
  font-size:15px;padding-inline:28px;line-height:1.7;
  text-shadow:0 1px 8px rgba(0,0,0,.8);
}
#scan .scan__cancel{
  position:absolute;inset-inline:0;margin-inline:auto;
  inset-block-end:calc(env(safe-area-inset-bottom) + 28px);
  width:min(58%,238px);height:48px;border-radius:12px;cursor:pointer;
  border:1px solid rgba(243,243,243,.4);background:rgba(0,0,0,.4);
  color:#F3F3F3;font-family:inherit;font-size:16px;font-weight:600;
}

/* --- skeletons: no pulse, no spinner --------------------------- */
.skel{background:var(--skeleton);border-radius:8px}
.skel--hi{background:var(--skeleton-hi)}

/* --- the keyboard, and everything that behaves like one ---------
   A ring drawn in --text, held one gap away from the control so the gap
   shows the page behind it. That pairing is 14:1 in both themes, so the
   ring is visible on the yellow CTA, on a card, and on a tinted banner
   alike — no per-component focus colour, and nothing to keep in sync.
   :focus-visible, not :focus: a thumb should not light this up. */
:focus-visible{
  outline:3px solid var(--text); outline-offset:2px; border-radius:4px;
}
.btn:focus-visible{ border-radius:var(--chamfer) }
.field:focus-visible{ outline-offset:1px }

/* --- motion: only when a machine moves ------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
}

/* --- RTL: mirror the box, keep each run readable --------------- */
:root[dir="rtl"] .app{unicode-bidi:plaintext}
:root[dir="rtl"] .btn,:root[dir="rtl"] .btn--2,:root[dir="rtl"] .btn--quiet{text-align:center}

/* ============================================================
   THE HOME MAP — full-bleed, on the owner's board (2026-08-23).
   #mapHost lives outside #app; the route on <body> shows it on the home
   alone, and .map-up arrives only once the vendored library painted.
   With the map up, #app turns to glass: touches fall through to the map
   everywhere except the pieces that are really there — the head, the
   bottom sheet, the foot. Without a style or a library, none of this
   fires and the list is the whole home.
   ============================================================ */
#mapHost{ display:none; position:fixed; inset:0; z-index:0; background:transparent }
body[data-route="entry"] #mapHost.map-try{ display:block; opacity:0 }
body[data-route="entry"] #mapHost.map-up{ opacity:1; transition:opacity .4s }
#app{ position:relative; z-index:1 }

body[data-route="entry"][data-map="up"] #app{ pointer-events:none }
body[data-route="entry"][data-map="up"] #app .head,
body[data-route="entry"][data-map="up"] #app .foot,
body[data-route="entry"][data-map="up"] #app .home,
body[data-route="entry"][data-map="up"] #app .card,
body[data-route="entry"][data-map="up"] #app .btn--quiet,
body[data-route="entry"][data-map="up"] #app .mapfab,
body[data-route="entry"][data-map="up"] #app .offline{ pointer-events:auto }
body[data-route="entry"][data-map="up"] .body{
  overflow:hidden; display:flex; flex-direction:column;
  padding-block-start:0; padding-block-end:0;
}

/* the open window onto the map, and the locate button floating in it */
.map-window{ flex:1; min-height:20vh; position:relative; pointer-events:none }
.mapfab{
  position:absolute; inset-inline-end:4px; inset-block-end:14px;
  width:48px; height:48px; border-radius:50%;
  background:var(--card); color:var(--text); font:inherit;
  border:1px solid var(--card-line, transparent);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 2px 10px rgba(0,0,0,.3); pointer-events:auto;
}

/* the bottom sheet over the map — and the flat list when there is none */
body[data-map="up"] .home{
  margin-inline:calc(var(--gutter) * -1); padding-inline:var(--gutter);
  background:var(--card); border-start-start-radius:18px;
  border-start-end-radius:18px; padding-block-start:4px;
  max-height:44vh; overflow-y:auto; overscroll-behavior:contain;
  box-shadow:0 -8px 24px rgba(0,0,0,.25);
}
body[data-map="up"] .home::-webkit-scrollbar{ width:0 }
.home__grab{ width:44px; height:4px; border-radius:2px; background:var(--hair);
             margin:6px auto 2px }
body[data-map="off"] .home{
  margin-inline:calc(var(--gutter) * -1); padding-inline:var(--gutter);
  background:var(--bg); padding-block-start:6px;
}
.home__bar{ display:flex; align-items:center; justify-content:space-between;
            padding-block:10px 6px }
.home__title{ font-size:13px; font-weight:700; letter-spacing:.06em;
              color:var(--muted) }
.btn--near{ min-height:44px; padding-inline:18px; border-radius:var(--r-btn,12px);
            background:var(--card); border:1px solid var(--card-line,transparent);
            color:var(--text); font:inherit; font-weight:700; font-size:15px }

/* a station row: a real target, a dot, a name, and a STATE in words */
.strow{ display:flex; align-items:center; gap:12px; inline-size:100%;
        min-height:56px; padding-block:8px; padding-inline:2px;
        background:none; border:0; border-bottom:1px solid var(--hair);
        color:var(--text); font:inherit; text-align:start; cursor:pointer }
.strow:last-child{ border-bottom:0 }
.strow__dot{ flex:none; width:10px; height:10px; border-radius:50% }
.strow__dot--ready{ background:var(--ok) }
.strow__dot--idle{ background:var(--idle) }
.strow__main{ flex:1; display:flex; flex-direction:column; gap:2px; min-width:0 }
.strow__name{ font-weight:700; font-size:16px }
.strow__sub{ color:var(--muted); font-size:12px }
.strow__meta{ flex:none; color:var(--muted); font-size:13px }

/* the pins the map draws — the brand octagon, a colour, never a count.
   Polished on the owner's word (2026-08-23): a solid ground so the tile
   never bleeds through, and the ready pin breathes a soft teal halo —
   killed with everything else under prefers-reduced-motion. */
.mappin{ width:44px; height:44px; position:relative; pointer-events:auto;
         cursor:pointer; display:flex; align-items:center; justify-content:center;
         background:none; border:0; padding:0 }
.mappin svg{ position:absolute; inset:0; width:100%; height:100%;
             stroke-width:5; filter:drop-shadow(0 2px 5px rgba(0,0,0,.3)) }
.mappin--ready svg{ stroke:var(--ok); fill:var(--card);
  filter:drop-shadow(0 2px 5px rgba(0,0,0,.28)) drop-shadow(0 0 12px rgba(9,204,176,.55)) }
.mappin--ready::after{ content:''; position:absolute; inset:-9px; border-radius:50%;
  background:radial-gradient(circle, rgba(9,204,176,.3), transparent 66%);
  z-index:-1; animation:pinbreathe 2.8s ease-in-out infinite }
@keyframes pinbreathe{ 0%,100%{ transform:scale(.82); opacity:.65 }
                       50%{ transform:scale(1.12); opacity:1 } }
.mappin--empty svg{ stroke:var(--idle); stroke-dasharray:7 5; fill:var(--card) }
.mappin--silent svg{ stroke:var(--idle); fill:var(--card); opacity:.85 }
.mappin__mark{ position:relative; color:var(--idle); font-weight:800;
               font-size:15px; line-height:1 }

/* ============================================================
   THE ROUND OF 2026-08-23 — the owner's three sentences over the
   competitor board: a home map worth looking at, a drawer of his own,
   and a serious polish pass. Everything below serves those three.
   ============================================================ */

/* --- a new screen fades in; a same-screen tick must not pulse.
       The class rides #app (never rebuilt), re-armed only on a route
       change — so the renting screen's once-a-second render stays still. */
#app.route-in{ animation:screenIn .24s ease-out }
@keyframes screenIn{ from{ opacity:0; transform:translateY(6px) } to{ opacity:1; transform:none } }

/* --- the screens do not move (owner, 2026-08-23 — he pinch-zoomed the
       station screen by accident). The document rules alone did not hold
       Safari, so EVERY element inside #app is pinned to pan only:
       double-tap and pinch find nothing to grab, on any screen. The map
       lives outside #app and keeps its own two-finger zoom. Text is not
       selectable — an app, not a document; what is typed still is. */
#app, #app *{ touch-action:pan-x pan-y }
body{ -webkit-user-select:none; user-select:none; -webkit-touch-callout:none }
input, textarea{ -webkit-user-select:text; user-select:text }
/* iOS zooms the page when a focused input reads under 16px — the one
   auto-zoom no meta stops. The hidden code input inherited 15. */
.otp__input{ font-size:16px }

/* --- the head's own doors ------------------------------------- */
.head__menu{
  position:absolute; inset-inline-start:12px; width:var(--tap); height:var(--tap);
  display:flex; align-items:center; justify-content:center;
  background:none; border:0; cursor:pointer; color:var(--text);
}
/* over a live map the head's controls stand on their own small grounds,
   and a soft fade of the page colour keeps the logo readable on any tile */
body[data-route="entry"][data-map="up"][data-view="map"] .head__menu,
body[data-route="entry"][data-map="up"][data-view="map"] .head__lang{
  background:var(--card); border:1px solid var(--card-line); border-radius:999px;
  box-shadow:0 2px 12px rgba(0,0,0,.18); color:var(--text);
}
body[data-route="entry"][data-map="up"][data-view="map"] .head{ z-index:2 }
body[data-route="entry"][data-map="up"][data-view="map"] .head::before{
  content:''; position:absolute; inset-block-start:0; inset-inline:0; height:135%;
  background:linear-gradient(180deg, var(--bg) 0%, transparent 100%);
  opacity:.8; z-index:-1; pointer-events:none;
}

/* --- the PIN SHEET (approved board: main-station) ---------------
   The tapped station's own card over the map — the way there, the live
   numbers asked after the tap, the price. No rent button: the printed
   code is the rent door. */
.pinsheet{
  position:absolute; inset-inline:0; bottom:112px; z-index:2;
  background:var(--card); border-radius:18px 18px 0 0;
  box-shadow:0 -8px 24px rgba(0,0,0,.25);
  padding:4px var(--gutter) 14px;
  animation:rise .26s cubic-bezier(.2,.8,.2,1);
}
.pinsheet__grab{
  display:flex; align-items:center; justify-content:center;
  width:100%; min-height:44px; margin:0; padding:0;
  background:none; border:0; cursor:pointer;
}
.pinsheet__grab span{ width:44px; height:4px; border-radius:2px; background:var(--hair) }
.pinhead{ display:flex; align-items:center; gap:12px; padding:0 0 2px }
.pinhead__name{ flex:1; font-weight:800; font-size:19px }
.pindir{
  min-height:44px; padding:0 14px; background:none;
  border:1px solid var(--idle-line); border-radius:999px;
  color:var(--ok-ink); font-size:13px; font-weight:700;
  display:inline-flex; align-items:center; gap:6px; text-decoration:none;
}
.pinsub{ display:flex; align-items:center; gap:8px; padding:0 28px 8px;
         color:var(--muted); font-size:13px }
.pinsub__d{ color:var(--ok-ink); font-weight:700 }
.pinlive{ display:flex; align-items:center; gap:14px; padding:12px 0 10px;
          border-top:1px solid var(--hair) }
.pincounts{ flex:1; display:flex; flex-direction:column; gap:2px }
.pinrow{ display:flex; align-items:center; min-height:34px }
.pinrow__word{ display:flex; align-items:center; gap:8px; font-size:13.5px }
.pinrow__word--ok{ color:var(--ok-ink) }
.pinrow__word--idle{ color:var(--muted) }
.pinrow__dot{ width:7px; height:7px; border-radius:50%; flex:none }
.pinrow__word--ok .pinrow__dot{ background:var(--ok);
  box-shadow:0 0 6px rgba(9,204,176,.55) }
.pinrow__word--idle .pinrow__dot{ background:var(--idle) }
.pinrow__lead{ flex:1; border-top:1.5px dashed var(--idle-line); margin:0 10px }
.pinrow__n{ font-weight:800; font-size:20px }
.pinrow__n--ok{ color:var(--ok-ink) }
.pinrow__n--idle{ color:var(--muted) }
.pinhair{ height:1px; background:var(--hair) }
.pinprice{ display:flex; align-items:center; justify-content:space-between;
           min-height:42px; border-top:1px solid var(--hair); font-size:14px }
.pinprice span:first-child{ color:var(--muted) }
.pinprice .fig{ font-weight:700 }

/* the little machine — iconography; the numbers beside it are the truth */
.pinmach{ width:104px; height:124px; flex:none; display:flex;
          align-items:flex-end; justify-content:center }
.pinmach__body{ width:100px; height:118px; background:var(--yellow);
  border-radius:9px 9px 7px 7px; display:flex; flex-direction:column;
  align-items:center; overflow:hidden;
  box-shadow:inset 0 -3px 6px rgba(31,36,38,.18), 0 8px 18px rgba(0,0,0,.4) }
.pinmach__cap{ width:100%; height:6px; background:var(--on-yellow); flex:none }
.pinmach__plaque{ width:86px; flex:none; margin-top:4px;
  background:var(--on-yellow); border-radius:6px; padding:3px }
.pinmach__qr{ display:flex; align-items:center; justify-content:center;
  background:linear-gradient(180deg,#EDFBAC,#D9F26B); border-radius:4px;
  height:30px; gap:4px }
.pinmach__qr i{ width:13px; height:13px; display:grid;
  grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(3,1fr); gap:1px }
.pinmach__qr i:first-child{ background:
  conic-gradient(var(--on-yellow) 0 0) 0 0/33% 33% no-repeat,
  conic-gradient(var(--on-yellow) 0 0) 100% 0/33% 33% no-repeat,
  conic-gradient(var(--on-yellow) 0 0) 50% 50%/33% 33% no-repeat,
  conic-gradient(var(--on-yellow) 0 0) 0 100%/33% 33% no-repeat,
  conic-gradient(var(--on-yellow) 0 0) 100% 100%/33% 33% no-repeat }
.pinmach__led{ width:4px; height:4px; border-radius:50%; background:var(--ok);
  box-shadow:0 0 5px rgba(9,204,176,.9); flex:none; margin:4px 0 }
.pinmach__grid{ width:100%; flex:1; display:grid;
  grid-template-columns:repeat(2,1fr); gap:5px 8px; padding:0 10px 8px }
.pinmach__slot{ display:flex; align-items:center; justify-content:center }
.pinmach__slot::before{ content:''; }
.pinmach__slot{ position:relative }
.pinmach__slot::after{ content:''; position:absolute; width:24px; height:8px;
  background:var(--on-yellow); border-radius:4px;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.6) }
.pinmach__slot i{ position:relative; z-index:1; width:8px; height:2px;
  border-radius:2px; background:var(--text);
  box-shadow:0 0 3px rgba(243,243,243,.9) }
.pinmach__slot i.dim{ opacity:.35; box-shadow:none }

/* the sheet and the drawer must stay touchable through the glass */
body[data-route="entry"][data-map="up"] #app .pinsheet,
body[data-route="entry"][data-map="up"] #app .drawer-scrim{ pointer-events:auto }

/* --- the station row, refined --------------------------------- */
.strow{ min-height:60px }
.strow__dot{
  width:16px; height:16px; border-radius:0;
  clip-path:polygon(29% 0,71% 0,100% 29%,100% 71%,71% 100%,29% 100%,0 71%,0 29%);
}
.strow__dot--ready{ filter:drop-shadow(0 0 6px rgba(9,204,176,.55)) }
.strow__name{ font-size:16.5px }
.strow__meta--ready{ color:var(--ok-ink); font-weight:600 }
.strow__meta--idle{ color:var(--muted) }

/* --- the drawer: his own door ---------------------------------- */
.drawer-scrim{
  position:absolute; inset:0; background:var(--scrim); z-index:64;
  animation:fade .2s ease-out;
}
.drawer{
  position:absolute; inset-block:0; inset-inline-start:0; width:min(84%, 20rem);
  background:var(--bg); border-inline-end:1px solid var(--card-line);
  box-shadow:0 0 44px rgba(0,0,0,.35);
  display:flex; flex-direction:column; gap:16px;
  padding:calc(env(safe-area-inset-top) + 16px) 16px calc(env(safe-area-inset-bottom) + 20px);
  overflow-y:auto; overscroll-behavior:contain;
  animation:drawerIn .28s cubic-bezier(.2,.8,.2,1);
}
@keyframes drawerIn{ from{ transform:translateX(-104%) } to{ transform:none } }
:root[dir="rtl"] .drawer{ animation-name:drawerInRtl }
@keyframes drawerInRtl{ from{ transform:translateX(104%) } to{ transform:none } }

.drawer__prof{
  background:var(--card); border:1px solid var(--card-line);
  border-radius:var(--r-card); padding:16px; display:flex; align-items:center;
  gap:14px; text-align:start; flex:none;
}
button.drawer__prof{ cursor:pointer; font:inherit; color:var(--text); width:100% }
button.drawer__prof:active{ background:var(--secondary-press) }
.drawer__ava{
  width:52px; height:52px; flex:none; background:var(--yellow); color:var(--on-yellow);
  display:flex; align-items:center; justify-content:center;
  font-weight:800; font-size:22px;
}
.drawer__who{ display:flex; flex-direction:column; gap:3px; min-width:0 }
.drawer__name{ font-weight:800; font-size:16.5px }

.drawer__list{ display:flex; flex-direction:column; gap:10px }
.drow{
  display:flex; align-items:center; gap:14px; width:100%; min-height:54px;
  background:var(--card); border:1px solid var(--card-line); border-radius:var(--r-card);
  padding-inline:16px; color:var(--text); font:inherit; font-weight:600;
  font-size:15.5px; cursor:pointer; text-align:start;
}
.drow:active{ background:var(--secondary-press) }
.drow svg{ flex:none; color:var(--muted) }
.drow__label{ flex:1 }
.drow__chev{ flex:none; color:var(--muted); display:flex }
:root[dir="rtl"] .drow__chev svg{ transform:scaleX(-1) }
.drow--out .drow__label{ color:var(--muted) }

/* --- «كيف تستخدم دوك» --- */
.steps{ list-style:none; display:flex; flex-direction:column }


/* --- ش2 on the approved board: plan cards, chips, and the AP CTA --- */
.plangrid{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr));
           gap:10px; margin-top:10px }
.plangrid:has(> :only-child){ grid-template-columns:minmax(0, 1fr) }
.plancard{
  text-align:start; background:var(--card); border:1px solid var(--idle-line);
  border-radius:16px; padding:14px; display:flex; flex-direction:column;
  gap:7px; color:var(--text);
}
.plancard--on{ background:var(--ok-surf); border:1.5px solid var(--ok) }
.plancard__top{ display:flex; align-items:center; justify-content:space-between;
                width:100% }
.plancard__name{ font-size:13.5px; font-weight:700 }
.plancard__tick{
  width:20px; height:20px; border-radius:50%; background:var(--ok);
  color:var(--bg); display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:800;
}
.plancard__price{ font-weight:800; font-size:24px; line-height:1 }
.plancard__cur{ font-size:13px; font-weight:700 }
.plancard__sub{ font-size:12px; color:var(--muted); line-height:1.65 }

.paychips{ display:flex; gap:8px }
.paychip{
  flex:1; height:48px; background:#FFFFFF; border:1.5px solid rgba(31,36,38,.1);
  border-radius:12px; color:#1F2426; display:flex; align-items:center;
  justify-content:center; gap:7px; cursor:pointer; font-family:inherit;
}
.paychip--on{ border-color:#09CCB0 }
.paychip--ap{ color:#050505 }
.paychip__pay{ font-weight:700; font-size:15px; letter-spacing:-.01em }
.paychip__tick{
  width:18px; height:18px; border-radius:50%; background:#09CCB0; color:#10211D;
  display:flex; align-items:center; justify-content:center;
  font-size:10px; font-weight:800; flex:none;
}
.paychip__sep{ width:1px; height:14px; background:rgba(31,36,38,.16) }
/* mada's own green fails AA at this size on white (2.98:1) — the hue
   holds, the lightness drops to clear 4.5:1, same move as the tokens */
.paychip [data-brand="mada"]{ font-weight:800; font-size:11.5px; color:#4C7C21 }
.paychip [data-brand="visa"]{ font-weight:800; font-size:11.5px; font-style:italic;
                              color:#1A1F71 }
.paychip__mc{ display:flex }
.paychip__mc i{ width:13px; height:13px; border-radius:50%; display:block }
.paychip__mc i:first-child{ background:#EB001B; opacity:.9 }
.paychip__mc i:last-child{ background:#F79E1B; opacity:.9;
                           margin-inline-start:-5px }

/* the white Apple Pay CTA — the one button beside the yellow chamfer */
.btn--ap{
  height:var(--cta); width:100%; border:0; cursor:pointer;
  display:flex; align-items:center; justify-content:center; gap:7px;
  background:#FFFFFF; color:#050505; border-radius:14px;
  font-weight:700; font-size:17px; font-family:inherit;
}
.btn--ap:active{ background:#EDEDED }

/* --- ش1: the unified LTR phone row, ringed teal in focus --- */
#pf:focus-within{ border-color:var(--ok);
                  box-shadow:0 0 0 4px rgba(9,204,176,.12) }
#pf input{ caret-color:var(--ok) }

/* --- ش11: the four illustrated steps --- */
.hstep{ display:flex; align-items:center; gap:16px }
.hstep + .hstep{ margin-top:18px }
.hstep__tile{ position:relative; flex:none }
.hstep__art{
  width:84px; height:84px; background:var(--card);
  border:1px solid var(--card-line); border-radius:18px;
  display:flex; align-items:center; justify-content:center;
}
.hstep__n{
  position:absolute; top:-7px; inset-inline-start:-7px;
  width:26px; height:26px; background:var(--yellow); color:var(--on-yellow);
  display:flex; align-items:center; justify-content:center;
  font-weight:800; font-size:13px;
}
.hstep__txt{ display:flex; flex-direction:column; gap:4px }
.hstep__title{ font-size:16px; font-weight:800 }
.hstep__sub{ font-size:12.5px; line-height:1.65; color:var(--muted) }
