/* ═══════════════════════════════════════════════════════════════════
   Mocca — Extended app sections (Tickets · Schedule · Map · Users ·
   Chat · Marketplace · Services)

   These page-views are injected into `.body-in` by sections.js and shown
   by the same data-page → data-view routing the dashboard uses. Styling
   is built entirely on the design-system tokens so every section inherits
   light/dark, the staging/preview env theater, and RTL for free.

   Aesthetic: calm + minimal, matching the restyled dashboard — flat
   surfaces, 1px borders, solid accents (no glows/gradients), UI font for
   labels, accent used sparingly as a single confident highlight.
   ═══════════════════════════════════════════════════════════════════ */

/* ── ROUTING ─────────────────────────────────────────────────────────
   Enumerated because CSS can't match data-view == data-page generically.
   Each active page-view becomes a bounded flex column so its inner .page
   can scroll (same contract as payments/metrics). */
.body[data-page="tickets-board"]     .page-view[data-view="tickets-board"],
.body[data-page="tickets-timeline"]  .page-view[data-view="tickets-timeline"],
.body[data-page="tickets-backlog"]   .page-view[data-view="tickets-backlog"],
.body[data-page="schedule-today"]    .page-view[data-view="schedule-today"],
.body[data-page="schedule-week"]     .page-view[data-view="schedule-week"],
.body[data-page="schedule-month"]    .page-view[data-view="schedule-month"],
.body[data-page="map"]               .page-view[data-view="map"],
.body[data-page="users-all"]         .page-view[data-view="users-all"],
.body[data-page="users-roles"]       .page-view[data-view="users-roles"],
.body[data-page="users-permissions"] .page-view[data-view="users-permissions"],
.body[data-page="chat"]              .page-view[data-view="chat"],
.body[data-page="services-backend"]  .page-view[data-view="services-backend"],
/* B63 W9 (147) — Settings' three NEW peers (Middleware/Assets/Styles), split
   off Frontend. Same third registration this list's own comments keep
   warning about — a route with the builder + the sidebar leaf but not HERE
   is a blank screen. */
.body[data-page="services-middleware"] .page-view[data-view="services-middleware"],
.body[data-page="services-frontend"] .page-view[data-view="services-frontend"],
.body[data-page="services-assets"]   .page-view[data-view="services-assets"],
.body[data-page="services-styles"]   .page-view[data-view="services-styles"],
.body[data-page="wallet-balance"]    .page-view[data-view="wallet-balance"],
.body[data-page="wallet-expenses"]   .page-view[data-view="wallet-expenses"],
/* B62 W-23 — Trips left the wallet for its own L1 route, so its show-row moved
   with it. The old `wallet-trips` row is gone: `navigate()` aliases that name to
   `trips`, so nothing can set `data-page="wallet-trips"` any more. */
.body[data-page="trips"]             .page-view[data-view="trips"],
/* B55 (Pablo, on Content, for the SECOND time: "Content is again missing on
   mobile landscape, I don't know what you're doing but it's not working") —
   ROOT CAUSE, and it was never the media query. `content.css` and `contacts.css`
   each carried their OWN copy of this show-row, because these routes are mounted
   by their own modules and were missing from the list. Those copies also set
   `flex-direction:column`, and at `(0,4,0)` they tie with the landscape rule
   `.shell.signed-in .page-view.sec-view{flex-direction:row-reverse}` — loading
   later, they won. So in landscape the view stayed a COLUMN while `.sec-tabs` was
   already styled as a `height:100%` vertical rail: the rail ate the whole
   viewport and pushed the page off-screen. The rows live HERE now, with every
   other route, and the parallel copies are gone — one list, one winner. */
.body[data-page="content"]           .page-view[data-view="content"],
.body[data-page="contacts"]          .page-view[data-view="contacts"],
.body[data-page="addresses"]         .page-view[data-view="addresses"],
/* B62 § S-11 — Companies. THIS LIST IS THE THIRD THING A NEW ROUTE NEEDS (after
   the builder and the sidebar leaf), and leaving it out is the defect Pablo has
   reported twice about Content: the view exists, `data-page` matches, and the
   screen is still blank because nothing ever makes the active view a flex
   column. The phone probe caught it here; the desktop one did not. */
.body[data-page="companies"]         .page-view[data-view="companies"],
/* B62 § S-03 — Drive. Same three registrations as every route before it: the
   builder, the sidebar leaf, and THIS row. */
.body[data-page="drive"]             .page-view[data-view="drive"],
.body[data-page="groceries"]         .page-view[data-view="groceries"],
.body[data-page="shop-catalog"]      .page-view[data-view="shop-catalog"],
.body[data-page="shop-menu"]         .page-view[data-view="shop-menu"],
.body[data-page="shop-stock"]        .page-view[data-view="shop-stock"],
/* B63 W3 — Shop ▸ Brands, the third registration (builder · sidebar leaf · this). */
.body[data-page="shop-brands"]       .page-view[data-view="shop-brands"],
/* B62 § S-18 — Support. The third registration, the one whose absence shows as a
   BLANK SCREEN on a phone while the desktop probe passes (the § S-11 lesson). */
.body[data-page="support"]           .page-view[data-view="support"],
/* Audit A11 · B63-026 — Surveys and Courses (learn.js), third registration. */
.body[data-page="surveys"]           .page-view[data-view="surveys"],
.body[data-page="courses"]           .page-view[data-view="courses"],
/* B62 § S-16 — Workshop ▸ Canvas. Third registration again, and it matters twice
   here: the editor is a flex COLUMN whose stage is the scroller, so without this
   row the sheet has no height at all and the page shows an empty toolbar. */
.body[data-page="workshop-canvas"]   .page-view[data-view="workshop-canvas"],
/* B62 § S-16 — Flowcharts. The list is an ordinary scrolling page, so this row
   is only the usual third registration; the editor is the engine's own modal. */
.body[data-page="workshop-flowcharts"] .page-view[data-view="workshop-flowcharts"],
/* B62 § S-16 — Suite. The third registration, and the only one of the three
   Workshop children that also needs `.sec-view` behaviour, because it is the
   only one with a `.sec-tabs` strip (his word: "tabs"). */
.body[data-page="workshop-suite"]    .page-view[data-view="workshop-suite"],
/* B62 wave 7 (Pablo: "just make sure this is integrated into the mocca front
   end ... architecture" -> "I can give comments when it's in the prototype") -
   the five Jockey member routes are page-views of THIS shell, so their show-rows
   live in this one list with every other route. A module stylesheet copy is the
   divergence the note above is about; jockey-app.css must never hold one. */
.body[data-page="jockey-reservas"]   .page-view[data-view="jockey-reservas"],
.body[data-page="jockey-espacios"]   .page-view[data-view="jockey-espacios"],
.body[data-page="jockey-carta"]      .page-view[data-view="jockey-carta"],
.body[data-page="jockey-pedidos"]    .page-view[data-view="jockey-pedidos"],
.body[data-page="jockey-cuenta"]     .page-view[data-view="jockey-cuenta"],
.body[data-page="buraco"]            .page-view[data-view="buraco"],
.body[data-page="finance"]           .page-view[data-view="finance"],
.body[data-page="library"]           .page-view[data-view="library"]{
  display:flex;flex-direction:column;flex:1;min-height:0;
  animation:secIn .34s var(--mk-ease) both;
}
/* Pablo B11-09: guarantee the sec-view page is the scroll surface on touch /
   small screens (Users▸All reported unscrollable). The flex chain already
   makes `.page` the scroller; pin overflow + momentum scrolling explicitly so
   no nested-flex quirk can swallow it, and let the table card grow naturally. */
.page-view.sec-view > .page{ overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain; }
.page-view[data-view="users-all"] .tbl-card{ overflow-x:auto; }
@keyframes secIn{ from{ opacity:0; transform:translateY(7px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){ .page-view{ animation:none !important; } }
/* Every page that isn't Payments uses an 18px-gap page (matches metrics). */
.body:not([data-page="payments"]) .page{ gap:18px; }
/* The Balance/Expenses/Income tab strip belongs to Payments only. */
.body:not([data-page="payments"]) .tabs{ display:none; }
/* The bottom bar is the mobile tab nav: it's populated dynamically from
   the active page's in-page tab strip. Show it ONLY when the active page
   actually has tabs (shell gets `.has-page-tabs` from sections.js); hide
   it everywhere else so it never shows an empty/stale bar. */
@media (max-width:600px){
  .shell.signed-in:not(.has-page-tabs) .tb{ display:none; }
}
/* When the active page has no tabs, collapse the (now-empty) bottom-bar
   grid row so it doesn't leave a phantom band at the foot of the screen. */
@media (max-width:600px) and (orientation:portrait){
  .shell.signed-in:not(.has-page-tabs){ grid-template-rows:1fr; }
}

/* MOBILE-H (landscape, short) — the in-page section tab strip turns into a
   vertical rail on the trailing edge (mirrors the Payments .tabs rail), the
   page sits beside it. The bottom .tb bar is portrait-only. Pablo 2026-06-21:
   "landscape it's a sidebar of sorts." */
@media (max-height:599px) and (orientation:landscape){
  .shell.signed-in .page-view.sec-view{ flex-direction:row-reverse; }
  .shell.signed-in .sec-view .page{ flex:1;min-width:0; }
  .shell.signed-in .sec-tabs{
    flex-direction:column;
    width:64px;height:100%;
    padding:6px;gap:3px;margin:0;
    border-bottom:none;
    border-inline-start:1px solid var(--border);
    background:var(--bg-1);
    overflow-x:hidden;overflow-y:auto;
    align-items:stretch;justify-content:space-evenly;
  }
  .shell.signed-in .sec-tabs .tab{
    flex:0;flex-direction:column;
    gap:3px;padding:8px 4px;
    width:100%;min-width:unset;height:auto;
    font-size:9px;text-align:center;
    border-radius:8px;
  }
  .shell.signed-in .sec-tabs .tab .mi{ font-size:20px; }
  /* B10-11 (Pablo): the tab label ("Design Systems" / "Sistemas de diseño")
     overflowed the 64px vertical rail — clamp it to one ellipsised line. */
  .shell.signed-in .sec-tabs .tab{ font-size:9.5px;line-height:1.12; }
  .shell.signed-in .sec-tabs .tab > [data-i18n],
  .shell.signed-in .sec-tabs .tab > span:not(.mi){
    display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
  /* Audit A11 — the one-line clamp cut the label on every tabbed route in
     Spanish ("Transacciones", "Razones de contacto", "Diapositivas" in a 64px
     rail): accessibility #1, no cropped critical info. Same rail, same 9.5px
     rhythm B51-11 approved — the label now takes a second line, hyphenated in
     the page's own language, instead of an ellipsis. */
  .shell.signed-in .sec-tabs .tab > [data-i18n],
  .shell.signed-in .sec-tabs .tab > span:not(.mi){
    white-space:normal;text-overflow:clip;overflow:visible;hyphens:auto;-webkit-hyphens:auto;overflow-wrap:anywhere; }
  .shell.signed-in .sec-tabs .tab.active{
    background:color-mix(in srgb, var(--accent) 13%, transparent);
    color:var(--accent);
  }
  .shell.signed-in .sec-tabs .tab.active .mi{ color:var(--accent); }
  /* B67 R67-052 — `flex:0` (basis 0) let each tab shrink to 16px and the tab's own overflow (B66 W1) cut its label to a
     half-line ("Gastos y", "Presu-") and the first icon at the top. Each tab is as tall as its icon + ONE line, and the
     label truncates with an ellipsis — 066-088 (Pablo, on this rail: "I prefer having 'Transact...' than the text
     wrapping on the box") supersedes the A11 wrap above. A rail with more tabs than fit scrolls. */
  .shell.signed-in .sec-tabs .tab{ flex:0 0 auto; }
  .shell.signed-in .sec-tabs .tab > [data-i18n],
  .shell.signed-in .sec-tabs .tab > span:not(.mi){ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; hyphens:manual; -webkit-hyphens:manual; }
}

/* TABLET (721–1024, tall enough not to be the landscape rail above) —
   B53-11, Pablo on the Frontend ▸ Components tab strip: "On tablet, each tab
   should be flex-col".

   The shell's own tablet rule already stacks EVERY nav element icon-above-label
   (shell.css: "Tablet 721-1024 · nav row, every nav element stacks
   icon-above-label"); the in-page tab strip was the one row still reading
   icon-beside-label, so on a tablet it was the odd one out in its own shell.
   Same grammar as the rail and the bottom bar: glyph over label, centred. */
@media (min-width:721px) and (max-width:1024px) and (min-height:600px){
  .shell.signed-in .sec-tabs .tab{
    flex-direction:column;
    gap:3px;padding:7px 14px;
    min-height:46px;
    text-align:center;line-height:1.16;
  }
  .shell.signed-in .sec-tabs .tab .mi{ font-size:19px; }
  /* A stacked tab is narrower than its label wants to be — one ellipsised line
     keeps the strip from growing a second row on a 4-tab section. */
  .shell.signed-in .sec-tabs .tab > [data-i18n],
  .shell.signed-in .sec-tabs .tab > span:not(.mi){
    display:block;max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
}

/* MOBILE-V (portrait): the in-page .sec-tabs strip must NOT sit on top of the
   page — it belongs in the bottom .tb bar (Pablo B12 C12: "tabs should be the
   bottom bar as we defined long ago. Don't change things I don't tell you to").
   syncBottomBar mirrors the strip into .tb and sets .has-page-tabs, so hide the
   in-page strip here and guarantee the bottom bar + top nav are both present. */
@media (max-width:600px) and (orientation:portrait){
  /* B51-12 (Pablo 2026-08-19: "The tabs on mobile portrait should be on the
     bottom and with a flex-col orientation, why did you change this? It's part
     of the shell it's so important") — supersedes B15 C9/C10 and restores the
     original B12 C12 rule. The in-page horizontal strip was a DUPLICATE of the
     bottom bar (`syncBottomBar` mirrors the same items into `.tb .ti`, which is
     already icon-above-label), so it is hidden here and the BOTTOM BAR is the
     tab nav on mobile portrait — one tab surface, at the bottom, flex-col. */
  .shell.signed-in .sec-tabs{ display:none !important; }
  .shell.signed-in.has-page-tabs .tb{ display:flex !important; }
  /* B51-11 (Pablo approved the mobile-LANDSCAPE tab rail: "Ok in mobile
     landscape it looks good") — that rail is now the reference rhythm for the
     portrait bottom bar too: 20px glyph over a 9.5px/1.12 label, clamped to one
     line, on a 44px touch floor. Same system in both orientations. */
  .shell.signed-in .tb .ti{ min-height:44px;font-size:9.5px;line-height:1.12;gap:3px; }
  .shell.signed-in .tb .ti .mi{ font-size:20px; }
  .shell.signed-in .tb .ti > [data-i18n],
  .shell.signed-in .tb .ti > span:not(.mi){
    display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
  /* The shell top nav is a sticky overlay on mobile-V; never let a section
     route hide it (Pablo B12 C11: "no navbar on mobile portrait in Frontend").
     Excludes the chat-thread fullscreen collapse, which intentionally hides it. */
  .shell.signed-in:not(:has(.body[data-page="chat"] .chat.show-thread)) .nav{ display:flex !important; }
  /* C29 (Pablo B15) — the chat list must fill the screen edge-to-edge on mobile
     portrait (no page gutter, no card chrome, full height). */
  .page-view[data-view="chat"] .page{ padding:0 !important; }
  .page-view[data-view="chat"] .page > .chat{ padding:0;gap:0;height:100%;flex:1 1 0; }
  .page-view[data-view="chat"] .chat-list{ border:0;border-radius:0;height:100%; }
}
/* MOBILE-H (landscape): the top nav becomes a left rail; guarantee it shows on
   section routes too (Pablo B12 C10: "navbar missing in mobile landscape"). */
@media (max-height:599px) and (orientation:landscape){
  /* B46 P6-ML11 — this rule exists to force the rail VISIBLE, not to choose its
     layout, but `display:flex !important` did both: it silently overrode the
     two-column `display:grid` rail in shell.css (this sheet loads later AND
     the selector is higher-specificity), so the signed-in rail stayed a single
     column while the 44px sizing still applied — 7×44 = 308px in a 237px rail,
     pushing the brand 23px off the top and the profile 24px below the bottom.
     It must assert the rail's REAL display. Keep in sync with the
     `.shell.signed-*/ .nav` grid block in shell.css; the portrait rule above
     stays `flex` because there the nav is a horizontal top bar, not the rail. */
  .shell.signed-in:not(:has(.body[data-page="chat"] .chat.show-thread)) .nav{ display:grid !important; }
}

/* ── SHARED: section toolbar (filter row under the page header) ─────── */
.sec-toolbar{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.sec-toolbar .spacer{ flex:1 1 auto; }
.sec-search{ display:inline-flex;align-items:center;gap:8px;
  height:34px;padding:0 12px;border-radius:var(--mk-radius-pill);
  background:var(--bg-1);border:1px solid var(--border);color:var(--fg-3);
  min-width:200px;transition:border-color var(--mk-t-fast); }
.sec-search:focus-within{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)); }
.sec-search .mi{ font-size:18px; }
.sec-search input{ border:0;background:transparent;outline:0;flex:1;min-width:0;
  font:500 13px var(--mk-font-ui);color:var(--fg-1); }

/* Segmented control — calm pill group, accent only on the active segment */
.seg{
  display:inline-flex;background:var(--bg-3);border:1px solid var(--border);
  border-radius:var(--mk-radius-pill);padding:3px;gap:2px;
}
.seg button{
  appearance:none;border:0;cursor:pointer;background:transparent;
  font:600 12px var(--mk-font-ui);color:var(--fg-2);
  padding:6px 14px;border-radius:var(--mk-radius-pill);
  display:inline-flex;align-items:center;gap:6px;
  transition:color var(--mk-t-fast),background var(--mk-t-fast);
}
.seg button .mi{ font-size:16px; }
/* B50-20 — the map layer selector is a `.seg` row now (five levels, all visible).
   It shares the Roadmap/Dashboard grammar; at compact widths it scrolls rather
   than widening the header. The `hidden` attribute it carries on the Places pane
   is honoured by the global guard in app-themes.css. */
.map-layer-seg{ max-width:100%;flex:0 1 auto; }
.map-layer-seg button{ white-space:nowrap; }
@media (max-width:900px){
  .map-layer-seg{ overflow-x:auto;scrollbar-width:none; }
  .map-layer-seg::-webkit-scrollbar{ display:none; }
  .map-layer-seg button{ flex:0 0 auto; }
}
@media (pointer:coarse){ .map-layer-seg button{ min-height:38px; } }
.seg button:hover{ color:var(--fg-1); }
.seg button.on{
  background:var(--bg-1);color:var(--accent-text);
  box-shadow:var(--shadow-xs);
}

/* Chip / filter button */
.chip{
  display:inline-flex;align-items:center;gap:6px;
  height:34px;padding:0 12px;border-radius:var(--mk-radius-pill);
  background:var(--bg-1);border:1px solid var(--border);
  color:var(--fg-2);font:600 12px var(--mk-font-ui);cursor:pointer;
  transition:border-color var(--mk-t-fast),color var(--mk-t-fast);
}
.chip:hover{ color:var(--fg-1);border-color:var(--fg-3); }
/* B50-25 — `.chip` is display:inline-flex, which overrides the UA `[hidden]` rule;
   JS toggles the design-system pill (and others) with `el.hidden`, so without this
   guard the attribute is a no-op. Same systemic trap as .page-fab-item. */
.chip[hidden]{ display:none; }
.chip .mi{ font-size:16px; }
.chip.accent{
  background:color-mix(in srgb, var(--accent) 9%, transparent);
  border-color:color-mix(in srgb, var(--accent) 24%, transparent);
  color:var(--accent-text);
}

/* Small KPI chips row some sections show above content */
.kpi-row{ display:flex;gap:12px;flex-wrap:wrap; }
.kpi{
  flex:1 1 160px;min-width:0;
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-md);padding:14px 16px;
  display:flex;flex-direction:column;gap:4px;
}
.kpi .kpi-l{ font:600 11px var(--mk-font-ui);letter-spacing:.04em;
  text-transform:none;color:var(--fg-3); }
.kpi .kpi-v{ font:700 24px var(--mk-font-ui);letter-spacing:-.02em;color:var(--fg-1);
  font-variant-numeric:tabular-nums; }
.kpi .kpi-d{ font:600 11px var(--mk-font-ui);display:inline-flex;align-items:center;gap:4px; }
.kpi .kpi-d .mi{ font-size:14px; }
.kpi .up{ color:var(--mk-success); }
.kpi .down{ color:var(--mk-debt); }

/* Avatar primitive (initials fallback handled inline) */
.av{
  width:32px;height:32px;border-radius:var(--mk-radius-pill);flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  font:700 12px var(--mk-font-ui);color:#fff;background:var(--accent);
  background-size:cover;background-position:center;overflow:hidden;
}
.av.sm{ width:26px;height:26px;font-size:10px; }
.av.xs{ width:20px;height:20px;font-size:8.5px; }
.av.lg{ width:40px;height:40px;font-size:14px; }
.av.av-img{ background:var(--bg-2); }
.av.av-img img{ width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block; }
/* Overflow bubble in a truncated avatar stack (Pablo 2026-06-22). Neutral
   surface so it reads as a count, not a person. */
.av-more{ background:var(--bg-3) !important;color:var(--fg-2) !important;
  font-weight:700;border:1.5px solid var(--bg-1); }
.av-stack{ display:inline-flex;align-items:center; }
.av-stack .av{ margin-inline-start:-7px;border:1.5px solid var(--bg-1); }
.av-stack .av:first-child{ margin-inline-start:0; }
.av-stack .av.xs{ margin-inline-start:-6px; }

/* ── P5-CHAT01 (Pablo 2026-08-04) — call simulation + info/compose sheets.
   Overlays mount on document.body so they work identically at every screen
   size. "Everything I do on one size I should be able to do on all" (Pablo). */
.chat-call{ position:fixed;inset:0;z-index:400;display:flex;flex-direction:column;align-items:center;justify-content:space-between;
  padding:6vh 24px 40px;background:radial-gradient(130% 92% at 50% -10%,#26324c 0%,#0b1421 68%);
  opacity:0;transition:opacity .24s var(--mk-ease);color:#fff;text-align:center; }
.chat-call.open{ opacity:1; }
.chat-call .cxl-stage{ display:flex;flex-direction:column;align-items:center;gap:16px;margin-top:6vh; }
.chat-call .cxl-av .av,.chat-call .cxl-remote-av .av{ width:118px;height:118px;font-size:38px;border:3px solid rgba(255,255,255,.16); }
.chat-call .cxl-nm{ font:700 24px var(--mk-font-ui);color:#fff; }
.chat-call .cxl-status{ font:600 15px var(--mk-font-ui);color:rgba(255,255,255,.72);letter-spacing:.03em;font-variant-numeric:tabular-nums; }
.chat-call:not(.connected) .cxl-av .av,.chat-call:not(.connected) .cxl-remote-av .av{ animation:cxlPulse 1.6s var(--mk-ease) infinite; }
@keyframes cxlPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(122,162,255,.42);} 50%{ box-shadow:0 0 0 20px rgba(122,162,255,0);} }
.chat-call .cxl-controls{ display:flex;align-items:flex-start;gap:16px; }
.cxl-ctl{ border:0;background:transparent;color:#fff;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:7px;font:600 11px var(--mk-font-ui);min-width:56px; }
.cxl-ctl-b{ width:56px;height:56px;border-radius:50%;background:rgba(255,255,255,.14);display:inline-flex;align-items:center;justify-content:center;transition:background var(--mk-t-fast),color var(--mk-t-fast); }
.cxl-ctl .mi{ font-size:24px; }
.cxl-ctl.on .cxl-ctl-b{ background:#fff;color:#12203a; }
.cxl-ctl:hover .cxl-ctl-b{ background:rgba(255,255,255,.24); }
.cxl-ctl.on:hover .cxl-ctl-b{ background:rgba(255,255,255,.86); }
.cxl-end .cxl-ctl-b{ background:var(--mk-danger);width:64px;height:64px; }
.cxl-end:hover .cxl-ctl-b{ background:#ff5f64; }
/* video variant */
.chat-call.is-video{ padding:0;justify-content:flex-end;background:#0b1421; }
.chat-call.is-video .cxl-stage{ position:absolute;inset:0;justify-content:flex-start;padding-top:7vh;margin:0;z-index:2;pointer-events:none; }
.chat-call.is-video .cxl-av{ display:none; }
.chat-call.is-video .cxl-nm,.chat-call.is-video .cxl-status{ position:relative;z-index:2;text-shadow:0 1px 10px rgba(0,0,0,.5); }
.cxl-remote{ position:absolute;inset:0;z-index:0;background:linear-gradient(160deg,#2b3a5c,#131d2e);display:flex;align-items:center;justify-content:center; }
.cxl-remote-av{ opacity:.92; }
.cxl-self{ position:absolute;inset-inline-end:16px;bottom:132px;width:92px;height:126px;border-radius:14px;background:#1b2740;border:1px solid rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.55);z-index:3;box-shadow:0 8px 24px rgba(0,0,0,.42); }
.cxl-self .mi{ font-size:26px; }
.chat-call.cam-off .cxl-self{ background:#12203a; }
.chat-call.is-video .cxl-controls{ position:relative;z-index:3;width:100%;justify-content:center;padding:22px 24px 30px;background:linear-gradient(0deg,rgba(0,0,0,.55),transparent); }

/* info + compose slide-over (desktop/tablet) → bottom sheet (mobile) */
.chat-sheet{ position:fixed;inset:0;z-index:380;opacity:0;transition:opacity .22s var(--mk-ease);pointer-events:none; }
.chat-sheet.open{ opacity:1;pointer-events:auto; }
.chat-sheet-scrim{ position:absolute;inset:0;background:color-mix(in srgb,var(--scrim,#0b1421) 46%,transparent); }
.chat-sheet-card{ position:absolute;inset-inline-end:0;inset-block:0;width:380px;max-width:92vw;background:var(--bg-1);border-inline-start:1px solid var(--border);
  display:flex;flex-direction:column;transform:translateX(100%);transition:transform .26s var(--mk-ease);box-shadow:-12px 0 40px rgba(0,0,0,.16); }
html[dir="rtl"] .chat-sheet-card{ transform:translateX(-100%); }
.chat-sheet.open .chat-sheet-card{ transform:none; }
.chat-sheet-hd{ display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--divider); }
.chat-sheet-t{ font:700 15px var(--mk-font-ui);color:var(--fg-1); }
.chat-sheet-close{ border:0;background:transparent;cursor:pointer;color:var(--fg-3);width:34px;height:34px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center; }
.chat-sheet-close:hover{ background:var(--bg-2);color:var(--fg-1); }
.chat-sheet-body{ flex:1;min-height:0;overflow-y:auto;padding:18px; }
.ci-hero{ display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;padding:8px 0 18px; }
.ci-hero .av{ width:76px;height:76px;font-size:26px; }
.ci-nm{ font:700 18px var(--mk-font-ui);color:var(--fg-1); }
.ci-sub{ font:500 12px var(--mk-font-ui);color:var(--mk-success); }
.ci-quick{ display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:18px; }
.ci-q{ border:1px solid var(--border);background:var(--bg-1);border-radius:12px;padding:12px 6px;display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;color:var(--fg-2);font:600 11px var(--mk-font-ui);transition:background var(--mk-t-fast),border-color var(--mk-t-fast); }
.ci-q .mi{ font-size:20px;color:var(--accent); }
.ci-q:hover{ background:var(--bg-2);border-color:var(--accent); }
.ci-q.on .mi{ color:var(--fg-3); }
.ci-mems{ display:flex;flex-direction:column;gap:2px; }
.ci-mem{ display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;border:0;border-radius:var(--mk-radius-md);background:transparent;color:var(--fg-1);text-align:start;font:inherit;cursor:pointer; }
.ci-mem.is-you{ cursor:default; }
button.ci-mem:hover{ background:var(--bg-2); }
.ci-mem:focus-visible{ outline:2px solid var(--accent);outline-offset:-2px; }
.ci-mem .av{ width:32px;height:32px;font-size:12px;flex:none; }
.ci-mem-t{ flex:1;min-width:0;display:flex;flex-direction:column; }
.ci-mem-t b{ font:600 13px var(--mk-font-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ci-mem-t i{ font:500 11.5px var(--mk-font-ui);font-style:normal;color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ci-mem-go{ color:var(--fg-3);font-size:20px; }
[dir="rtl"] .ci-mem-go{ transform:scaleX(-1); }
.ci-sec-h{ display:block;font:700 11px var(--mk-font-ui);letter-spacing:.04em;text-transform:uppercase;color:var(--fg-3);margin-bottom:10px; }
.ci-media{ display:grid;grid-template-columns:repeat(3,1fr);gap:8px; }
.ci-media .shot-thumb{ width:100%;height:74px; }
@media (max-width:600px){
  .chat-sheet-card{ inset-inline:0;inset-block:auto 0;width:auto;max-width:none;max-height:86dvh;border-inline-start:0;border-top:1px solid var(--border);border-radius:18px 18px 0 0;transform:translateY(100%); }
  html[dir="rtl"] .chat-sheet-card{ transform:translateY(100%); }
  .chat-sheet.open .chat-sheet-card{ transform:none; }
  .chat-call .cxl-controls{ gap:12px; } .cxl-ctl{ min-width:52px; }
}

/* Status pill (shared) */
.pill{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 10px;border-radius:var(--mk-radius-pill);
  font:600 11px var(--mk-font-ui);letter-spacing:.01em;
}
.pill .dot{ width:6px;height:6px;border-radius:50%;background:currentColor; }
.pill.ok{ color:var(--mk-success);
  background:color-mix(in srgb, var(--mk-success) 12%, transparent); }
.pill.warn{ color:var(--mk-warning);
  background:color-mix(in srgb, var(--mk-warning) 14%, transparent); }
.pill.err{ color:var(--mk-danger);
  background:color-mix(in srgb, var(--mk-danger) 12%, transparent); }
.pill.mute{ color:var(--fg-3);
  background:color-mix(in srgb, var(--fg-3) 12%, transparent); }
.pill.accent{ color:var(--accent-text);
  background:color-mix(in srgb, var(--accent) 12%, transparent); }

/* ═══ TICKETS · BOARD (kanban) ═══════════════════════════════════════ */
.kanban{
  flex:1 1 0;min-height:0;
  display:grid;grid-template-columns:repeat(4, minmax(240px,1fr));
  gap:14px;overflow-x:auto;padding-bottom:4px;align-items:start;
}
.kb-col{
  background:var(--bg-2);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);padding:12px;
  display:flex;flex-direction:column;gap:10px;min-height:0;
}
.kb-col-h{ display:flex;align-items:center;gap:8px;padding:2px 4px; }
.kb-col-h .nm{ font:700 13px var(--mk-font-ui);color:var(--fg-1); }
.kb-col-h .ct{
  font:700 11px var(--mk-font-ui);color:var(--fg-3);
  background:var(--bg-3);border-radius:var(--mk-radius-pill);
  padding:1px 8px;font-variant-numeric:tabular-nums;
}
.kb-col-h .swatch{ width:8px;height:8px;border-radius:3px;flex:0 0 auto; }
.kb-col-h .add{
  margin-inline-start:auto;width:24px;height:24px;border-radius:7px;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--fg-3);cursor:pointer;border:0;background:transparent;
  transition:background var(--mk-t-fast),color var(--mk-t-fast);
}
.kb-col-h .add:hover{ background:var(--bg-3);color:var(--accent-text); }
.kb-col-h .add .mi{ font-size:18px; }
.kb-cards{ display:flex;flex-direction:column;gap:10px;min-height:0; }
.kb-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-md);padding:12px;
  /* B54 (Pablo, split by orientation) — HORIZONTAL variants (desktop, mobile
     landscape: narrower columns) put the summary across the full width and a
     2×2 grid under it: type chip + key on the start side, priority+avatar and
     the due date on the end side. VERTICAL variants (tablet, mobile portrait)
     keep the B53-12 side column. One DOM, two templates. */
  /* B61 - ONE layout at every breakpoint (see sections.js cardHtml): a title row
     with the key to its left, then a true 2x2 grid. The card itself is just the
     column that stacks those two blocks; the alignment lives in .kb-card-grid. */
  display:flex;flex-direction:column;gap:10px;cursor:grab;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast),transform var(--mk-t-fast),opacity var(--mk-t-fast);
}
.kb-card-main{ min-width:0;display:flex;flex-direction:row;align-items:baseline;gap:7px; }
.kb-card-main .tt{ flex:1 1 auto;min-width:0; }
/* B61 - the key has ONE home now (to the left of the name) instead of moving
   between .kb-card-main and .kb-card-meta per breakpoint. */
.kb-key-pre{ display:inline-block;flex:0 0 auto;font:700 11px var(--mk-font-ui);
  letter-spacing:.04em;color:var(--fg-3);font-variant-numeric:tabular-nums; }
.kb-card-main .kb-lock{ flex:0 0 auto;font-size:14px;color:var(--fg-3); }
/* the 2x2: type / priority+avatar on row one, parent / due date on row two.
   grid-auto-rows equalises the two rows and align-items centres every cell, so
   the four items line up both ways - which is the whole comment. */
.kb-card-grid{ display:grid;grid-template-columns:minmax(0,1fr) auto;
  grid-auto-rows:minmax(22px,auto);gap:6px 10px;align-items:center;min-width:0; }
.kb-cell{ min-width:0;display:flex;align-items:center;gap:6px; }
.kb-cell-wp,.kb-cell-due{ justify-content:flex-end;text-align:end; }
.kb-cell-type,.kb-cell-parent{ justify-content:flex-start; }
.kb-cell-wp,.kb-cell-due{ max-width:150px; }
.kb-cell:empty{ display:none; }
/* B55 (Pablo: "This is redundant, take it out on all ticket cards") — the tag
   chips are gone from the CARD: the type chip in `.kb-card-meta` already says what
   kind of ticket it is, and the tags repeated it. `.kb-tag` itself stays for the
   backlog TABLE, the detail panel and the hover tooltip, which are not cards. */
.kb-card .kb-tags{ display:none; }

.kb-type-chip{ display:inline-flex;align-items:center;gap:5px;max-width:100%;padding:2px 8px 2px 6px;
  border-radius:999px;background:var(--bg-3);color:var(--fg-2); }
.kb-type-chip .kb-type-l{ font:700 10.5px/1.5 var(--mk-font-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.kb-type-chip .kb-type-l:empty{ display:none; }
/* B55 (Pablo: "On horizontal layouts, this should be moved up. This is not
   aligned with the left column") — the side column starts at the TOP of its grid
   row and carries the same 5px rhythm as `.kb-card-meta`, so priority+avatar sits
   on the type chip's line and the due date on the key's. */
/* B60 (Pablo: "Why did you break the items on the ticket cards with a line in the
   middle? They used to look much better" + "On the mobile portrait and tablet view,
   the card also has a vertical line. Why? please remove it") — the side column had
   grown a `border-inline-start` divider. It is gone at every breakpoint; the gap
   between the two columns is the separation. */

/* priority + avatar ride together — Pablo asked for this in BOTH orientations
   ("tie the avatar and priority as flex-row so that we don't waste space"). */
.kb-wp{ display:inline-flex;flex-direction:row;align-items:center;gap:6px; }

/* B60 - SYMMETRY on the vertical variants (Pablo: "the project tag here looks worse
   because now one item takes 4 lines while the right side is using 3 lines. Maybe
   here we can show the ticket key right before the title ... I want there to be
   simmetry"). On a narrow card the meta column stacked type / key / project as three
   rows against a two-row side column. So on those variants the KEY moves up onto the
   title's line (his own suggestion) and what is left - type chip + project chip -
   sits on ONE row: two rows on the left, two on the right. The key is rendered in
   ONE place per breakpoint, never twice. */
/* B61 - .kb-key-pre is always visible; see .kb-card-main above. */
/* B61 - the two orientation overrides that used to re-flow this card are GONE.
   They were the source of the misalignment: the key had two homes, the meta
   column stacked while the side column did not, and the two columns could only
   line up by accident. One layout, measured once. */
.kb-card:active{ cursor:grabbing; }
.kb-card.dragging{ opacity:.45;border-style:dashed; }
/* Non-movable ticket (Pablo 2026-06-21): it is ACTIVE — full opacity, normal
   card chrome — it simply can't be dragged yet. A small lock glyph signals
   why; the cursor is default (not grab). No dimmed/disabled look. */
.kb-card-locked{ cursor:default; }
.kb-card-locked:active{ cursor:default; }
/* B60 (Pablo: "Why is there a question mark pointer? Please remove it from every
   component in the prototype") — a `title` needs no cursor of its own, and on
   `.wl-req` the rule was landing on the INPUT itself (the class marks required
   fields), so typing in a required field showed a help cursor. */
.kb-lock{ font-size:13px;color:var(--fg-3);margin-inline-start:2px; }

/* Rich ticket hover tooltip — shared by board, timeline (gantt) & backlog.
   Floating card with an info-dense meta grid (Pablo 2026-06-21). */
.tkt-tip{
  position:fixed;z-index:1200;top:0;left:0;width:300px;max-width:calc(100vw - 16px);
  background:var(--bg-1);border:1px solid var(--border-strong,var(--border));
  border-radius:var(--mk-radius-lg);box-shadow:var(--shadow-lg);
  padding:13px 14px;pointer-events:none;
  opacity:0;transform:translateY(4px);transition:opacity .12s,transform .12s;
}
.tkt-tip.show{ opacity:1;transform:none; }
.tkt-tip-h{ display:flex;align-items:center;gap:7px; }
.tkt-tip-h .kb-type-ic{ font-size:16px;color:var(--accent-text); }
.tkt-tip-id{ font:700 11px var(--mk-font-ui);letter-spacing:.04em;color:var(--fg-2);font-variant-numeric:tabular-nums; }
.tkt-tip-type{ margin-inline-start:auto;font:600 10.5px var(--mk-font-ui);color:var(--fg-3);
  text-transform:none;letter-spacing:.05em; }
.tkt-tip-title{ font:650 14px var(--mk-font-ui);color:var(--fg-1);line-height:1.4;margin:7px 0;text-wrap:pretty; }
.tkt-tip-tags{ display:flex;flex-wrap:wrap;gap:5px;margin-bottom:9px; }
.tkt-tip-meta{ display:grid;grid-template-columns:1fr 1fr;gap:9px 12px;
  border-top:1px solid var(--divider);padding-top:10px; }
.tkt-tip-meta > div{ display:flex;flex-direction:column;gap:3px;min-width:0; }
.tkt-tip-l{ font:600 9.5px var(--mk-font-ui);letter-spacing:.06em;text-transform:none;color:var(--fg-3); }
.tkt-tip-v{ display:inline-flex;align-items:center;gap:5px;font:600 12px var(--mk-font-ui);color:var(--fg-1); }
.tkt-tip-v .mi{ font-size:15px; }
.tkt-tip-v .dot{ width:8px;height:8px;border-radius:50%;flex:0 0 auto; }
.tkt-tip-v .av{ width:18px;height:18px;font-size:8px; }
.tkt-tip-v.prio-hi{ color:var(--mk-danger); }
.tkt-tip-lock{ display:flex;align-items:center;gap:6px;margin-top:10px;
  font:600 11px var(--mk-font-ui);color:var(--fg-3); }
.tkt-tip-lock .mi{ font-size:14px; }
.kb-col.drag-over{
  background:color-mix(in srgb, var(--accent) 9%, var(--bg-2));
  outline:2px dashed color-mix(in srgb, var(--accent) 42%, transparent);
  outline-offset:-2px;
}
/* Disabled drop column (Pablo 2026-06-21) — a ticket can't land here; show a
   blocked tint + the lock affordance while dragging over it. */
.kb-col-nodrop .kb-col-lock{ font-size:14px;color:var(--fg-3); }
.kb-col.drag-blocked{
  background:color-mix(in srgb, var(--mk-danger) 8%, var(--bg-2));
  outline:2px dashed color-mix(in srgb, var(--mk-danger) 45%, transparent);
  outline-offset:-2px;cursor:not-allowed;
}
.kb-col.drag-blocked .kb-cards{ opacity:.5; }
/* Status sub-divisions inside a column. The existing tickets are ALWAYS
   sorted into their box (Pablo 2026-06-21: "existing tickets should already
   be sorted to the box they're currently in, not show up below in a list").
   The boxes are visible at rest; the hovered one lights up while dragging. */
.kb-col-sub .kb-cards{ gap:10px; }
.kb-subzone{ border:1px dashed var(--border);border-radius:var(--mk-radius-md);
  padding:8px;background:color-mix(in srgb,var(--bg-1) 45%,transparent);
  transition:background var(--mk-t-fast),border-color var(--mk-t-fast); }
.kb-subzone-h{ display:flex;align-items:center;gap:6px;
  font:700 10.5px var(--mk-font-ui);letter-spacing:.04em;text-transform:none;
  color:var(--fg-3);margin-bottom:8px; }
.kb-subzone-dot{ width:6px;height:6px;border-radius:50%;background:var(--fg-3);flex:0 0 auto; }
.kb-subzone-cards{ display:flex;flex-direction:column;gap:10px;min-height:22px; }
.kb-subzone.drag-over{
  background:color-mix(in srgb, var(--accent) 12%, transparent);
  border-color:var(--accent);border-style:solid;
}
.kb-subzone.drag-over .kb-subzone-dot{ background:var(--accent); }
.kb-card:hover{ border-color:color-mix(in srgb, var(--accent) 32%, var(--border));
  box-shadow:var(--shadow-sm);transform:translateY(-1px); }
.kb-card .tt{ font:600 13px var(--mk-font-ui);color:var(--fg-1);line-height:1.4;
  letter-spacing:-.01em;text-wrap:pretty; }
.kb-card .tt[contenteditable]{ outline:none;border-radius:5px;
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 30%,transparent);padding:1px 3px;margin:-1px -3px; }
.kb-card .tt[data-new]:empty::before{ content:'New task…';color:var(--fg-3); }
.kb-tags{ display:flex;gap:6px;flex-wrap:wrap; }
.kb-tag{
  font:600 10px var(--mk-font-ui);letter-spacing:.02em;
  padding:2px 8px;border-radius:var(--mk-radius-pill);
  color:var(--fg-2);background:var(--bg-3);
}
.kb-tag.a{ color:var(--accent-text);background:color-mix(in srgb,var(--accent) 11%,transparent); }
.kb-tag.p{ color:var(--mk-debt);background:color-mix(in srgb,var(--mk-debt) 11%,transparent); }
.kb-tag.g{ color:var(--mk-success);background:color-mix(in srgb,var(--mk-success) 12%,transparent); }
/* B54 — the card has no `.kb-foot` any more: the type chip and the key are the
   `.kb-card-meta` grid area. `.kb-foot` survives for the other ticket surfaces
   that still render one (backlog rows, the detail panel). */
.kb-foot{ display:flex;align-items:center;justify-content:space-between;gap:8px; }

.kb-id-wrap{ display:inline-flex;align-items:center;gap:6px;min-width:0; }
.kb-type-ic{ font-size:15px;color:var(--fg-3);flex:0 0 auto; }
.kb-foot .id,.kb-card-meta .id{ font:700 11px var(--mk-font-ui);letter-spacing:.04em;color:var(--fg-3);font-variant-numeric:tabular-nums; }
.kb-prio{ display:inline-flex;align-items:center;gap:5px;font:600 11px var(--mk-font-ui); }
.kb-prio .mi{ font-size:15px; }
.kb-prio.hi{ color:var(--mk-danger); }
.kb-prio.md{ color:var(--mk-warning); }
.kb-prio.lo{ color:var(--fg-3); }

/* ── B50-05 — ticket quick-edit controls (board card · backlog row · timeline) ──
   Pablo: "I don't see the option to re-assign or re-prioritize or re-schedule in
   the card. Please add them (and add a due date to the tickets) this goes for all
   the views of the tickets." Three chips, one shared popover. They read as quiet
   metadata at rest and only reveal their affordance on hover/focus, so the card
   doesn't turn into a toolbar. */
.kb-qs{ display:flex;align-items:center;gap:4px;flex:0 0 auto; }
.kb-prio,.kb-who,.kb-due{ border:1px solid transparent;background:none;cursor:pointer;
  border-radius:var(--mk-radius-pill);padding:2px 5px;min-height:24px;
  transition:background var(--mk-t-fast),border-color var(--mk-t-fast); }
.kb-prio:hover,.kb-who:hover,.kb-due:hover{ background:var(--bg-2);border-color:var(--border); }
.kb-prio:focus-visible,.kb-who:focus-visible,.kb-due:focus-visible{ outline:2px solid var(--accent);outline-offset:1px; }
.kb-who{ display:inline-flex;align-items:center;padding:2px; }
.kb-due{ display:inline-flex;align-items:center;gap:4px;font:600 11px/1 var(--mk-font-ui);
  color:var(--fg-3);font-variant-numeric:tabular-nums;white-space:nowrap; }
.kb-due .mi{ font-size:14px; }
/* A ticket with no due date at all reads as an open question, not as data. */
.kb-due[data-tk-due="none"]{ border-color:var(--border);border-style:dashed;color:var(--fg-3); }
.kb-due[data-tk-due="open"]{ color:var(--accent-text,var(--accent));border-color:color-mix(in srgb,var(--accent) 30%,transparent); }
.kb-due[data-tk-due="set"]{ color:var(--fg-2); }
@media (pointer:coarse){ .kb-prio,.kb-who,.kb-due{ min-height:44px;padding:2px 10px; } }
/* Timeline: the in-bar avatar is a button now, so it needs the pill's own reset. */
.gantt-bar-who{ border:0;background:none;padding:0;margin:0;cursor:pointer;display:inline-flex;flex:0 0 auto; }
.gantt-bar-prio-box.in-bar{ cursor:pointer; }
.gantt-vcard .gantt-bar-prio-box{ border:1px solid var(--divider);cursor:pointer; }

/* The shared quick-edit popover. Rides `.cs-menu` (the app's one dropdown look)
   and only adds row decoration. */
.tk-qm{ position:fixed;z-index:2300;min-width:210px;max-height:min(320px,calc(100dvh - 90px));overflow-y:auto; }
/* B67 R21 (R67-083) — the menu is placed by its own `left` (sections.js tkOpenQuickMenu); the shared .cs-menu anchor
   (inset-inline-end:0) stretched it from the chip to the screen edge (834px for three projects at 1470). */
.tk-qm{ right:auto; }
/* B65 W12 (065-109 "Why can't I select the status?" · 065-112 "This button doesn't work") — a
   `.cs-menu` is only visible as `.cs.open > .cs-menu`; the quick menu hangs off <body>
   with no `.cs` parent, so every quick edit (status, priority, assignee, due, project)
   opened invisible. It shows itself. */
.tk-qm.open{ opacity:1;pointer-events:auto;transform:none; }
/* B65 W12 (065-110) — Created beside Due, one row of the ticket panel. */
.tk-dates{ display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:9px 0;border-top:1px solid var(--border); }
.tk-date{ display:flex;flex-direction:column;align-items:flex-start;gap:5px;min-width:0; }
.tk-date-l{ font:500 13px var(--mk-font-ui);color:var(--fg-3); }
.tk-date-v{ display:inline-flex;align-items:center;gap:5px;font:600 12px/1 var(--mk-font-ui);color:var(--fg-1);padding:5px 0;font-variant-numeric:tabular-nums; }
.tk-date-v .mi{ font-size:15px;color:var(--fg-3); }
.tk-tl-open-wrap{ margin-top:14px; }
.tk-tl{ padding-top:4px; }
.tk-qm-item{ display:flex;align-items:center;gap:9px;cursor:pointer; }
.tk-qm-ic{ font-size:16px;color:var(--fg-3);flex:0 0 auto; }
.tk-qm-item.on .tk-qm-ic{ color:var(--accent-text,var(--accent)); }
.tk-qm-ic.prio-hi{ color:var(--mk-danger); }
.tk-qm-ic.prio-md{ color:var(--mk-warning); }
.tk-qm-sub{ margin-inline-start:auto;font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.tk-qm-dot{ display:inline-block;width:9px;height:9px;border-radius:50%;flex:0 0 auto; }
.tk-qm-div{ height:1px;background:var(--border);margin:5px 2px; }

/* B50-06 — the detail panel edits in place. */
.tk-title-ed{ font:700 17px/1.35 var(--mk-font-ui);color:var(--fg-1);margin-bottom:10px;
  text-wrap:pretty;border:1px solid transparent;border-radius:9px;padding:5px 7px;margin-inline:-7px;
  transition:background var(--mk-t-fast),border-color var(--mk-t-fast);cursor:text; }
.tk-title-ed:hover{ background:var(--bg-2);border-color:var(--border); }
.tk-title-ed:focus{ outline:0;background:var(--bg-1);border-color:var(--accent); }
.tk-status{ display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  padding:4px 9px;border:1px solid var(--border);border-radius:var(--mk-radius-pill);
  background:var(--bg-1);color:var(--fg-1);font:600 12px/1 var(--mk-font-ui); }
.tk-status:hover{ border-color:var(--accent); }
.tk-status .mi{ font-size:15px;color:var(--fg-3); }
@media (pointer:coarse){ .tk-status{ min-height:44px; } }
/* B57 — the ticket's own message thread (Pablo: "There should be a message thread on
   each ticket … a user can always create a chat thread for a specific ticket (to a
   group or to a person)"). Bubbles reuse the app's chat proportions; the composer is
   the shared component, so nothing here styles an editor. */
.tk-sec{ display:flex;align-items:center;gap:7px;margin:18px 0 8px;font:700 10.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3); }
.tk-sec .mi{ font-size:16px; }
/* B63-046 — the Discussion section is now a plain list of chats (Trips'
   pattern): each row previews the chat and opens the real thing on a pushed
   slide, no inline composer or audience picker in the main panel body. */
.tk-chats{ display:flex;flex-direction:column;gap:6px;margin-bottom:10px; }
.tk-chat-row{ display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1);
  cursor:pointer;text-align:start;transition:border-color var(--mk-t-fast),background var(--mk-t-fast); }
.tk-chat-row:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--border));background:color-mix(in srgb,var(--accent) 5%,var(--bg-1)); }
.tk-chat-ic{ flex:0 0 auto;font-size:18px;color:var(--fg-3); }
.tk-chat-b{ flex:1;min-width:0;display:flex;flex-direction:column;gap:1px; }
.tk-chat-nm{ font:700 12.5px/1.3 var(--mk-font-ui);color:var(--fg-1); }
.tk-chat-prev{ font:500 11.5px/1.3 var(--mk-font-ui);color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.tk-chat-tm{ flex:0 0 auto;font:600 10.5px var(--mk-font-ui);color:var(--fg-3); }
.tk-chat-go{ flex:0 0 auto;font-size:16px;color:var(--fg-3); }

/* ═══ TICKETS · TIMELINE (activity feed) ═════════════════════════════ */
.feed{ display:flex;flex-direction:column;gap:0;max-width:720px; }
.feed-row{ display:grid;grid-template-columns:120px 1fr;gap:16px; }
.feed-row .when{ font:600 12px var(--mk-font-ui);color:var(--fg-3);
  text-align:end;padding-top:12px; }
.feed-track{ position:relative;padding:12px 0 12px 22px; }
.feed-track::before{ content:"";position:absolute;inset-inline-start:5px;top:0;bottom:0;
  width:2px;background:var(--divider); }
.feed-row:first-child .feed-track::before{ top:18px; }
.feed-row:last-child  .feed-track::before{ bottom:auto;height:18px; }
.feed-node{ position:absolute;inset-inline-start:0;top:16px;width:12px;height:12px;
  border-radius:50%;background:var(--bg-1);border:2px solid var(--accent); }
.feed-node.done{ background:var(--accent);border-color:var(--accent); }
.feed-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-md);padding:12px 14px;
  display:flex;flex-direction:column;gap:6px;
}
.feed-card[data-ticket]{ cursor:pointer;transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast); }
.feed-card[data-ticket]:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--border));box-shadow:var(--shadow-sm); }
.feed-card .ft{ font:600 13px var(--mk-font-ui);color:var(--fg-1); }
.feed-card .fb{ font:500 12px var(--mk-font-ui);color:var(--fg-2);line-height:1.5; }
.feed-by{ display:inline-flex;align-items:center;gap:7px;margin-top:2px;
  font:600 11px var(--mk-font-ui);color:var(--fg-3); }

/* ═══ DATA TABLE (Users · Backlog) ═══════════════════════════════════ */
.tbl-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);overflow:hidden;
  /* B67 R67-008 — a flex child of the page column with overflow:hidden shrinks below its rows (min-height resolves to 0):
     Backlog and Users lost their last rows at every size but the widest (phone landscape showed only the header) and
     nothing scrolled to them. The card keeps its height; the page scrolls. */
  flex-shrink:0;
}
.tbl{ width:100%;border-collapse:collapse;font:500 13px var(--mk-font-ui); }
/* The .page gutter (.page > :not(.page-h){padding-inline:24px}) lands as
   padding ON this bordered card, insetting the table so the header
   background stops short of the card edges. Convert that gutter to MARGIN
   for the table card so the table — and its header background — fill the
   whole card (Pablo 2026-06-19). */
.sec-view .page > .tbl-card{ padding-inline:0;margin-inline:24px; }
.sec-view .page > .tbl-card:last-child{ padding-bottom:0;margin-bottom:24px; }
.tbl thead th{
  text-align:start;padding:12px 16px;
  font:600 11px var(--mk-font-ui);letter-spacing:.04em;text-transform:none;
  color:var(--fg-3);background:var(--bg-2);
  border-bottom:1px solid var(--border);white-space:nowrap;
}
.tbl thead th.sortable{ cursor:pointer;user-select:none;transition:color var(--mk-t-fast); }
.tbl thead th.sortable:hover{ color:var(--accent-text); }
.tbl thead th .sort-caret{ font-size:14px;vertical-align:-3px;margin-inline-start:4px;color:var(--accent-text); }
.tbl tbody td{ padding:12px 16px;border-bottom:1px solid var(--divider);color:var(--fg-1);
  vertical-align:middle; }
.tbl tbody tr:last-child td{ border-bottom:0; }
.tbl tbody tr{ transition:background var(--mk-t-fast);cursor:pointer; }
.tbl tbody tr:hover{ background:var(--bg-2); }
.tbl .u-cell{ display:flex;align-items:center;gap:10px; }
.tbl .u-name{ font:600 13px var(--mk-font-ui);color:var(--fg-1); }
.tbl .u-mail{ font:500 12px var(--mk-font-ui);color:var(--fg-3); }
.tbl .num{ font-variant-numeric:tabular-nums;color:var(--fg-2); }
.tbl .row-act{ color:var(--fg-3);text-align:end; }
.tbl .row-act .mi{ font-size:18px; }
/* W673-R2 (Pablo 2026-07-23, visual-check form pick "collapse to stacked
   cards"): on narrow screens (below tablet) the 6-column Users table forced a
   horizontal scroll. Collapse each row into a self-contained card — member as
   the header line, every other column a label:value row (labels from the th
   keys via data-label, so all 3 languages render on navigation). hide-sm cols
   are un-hidden here since a card has room for every field. */
@media (max-width:768px){
  .page-view[data-view="users-all"] .tbl-card{ overflow:visible;border:0;background:transparent;border-radius:0; }
  .page-view[data-view="users-all"] .tbl,
  .page-view[data-view="users-all"] .tbl tbody,
  .page-view[data-view="users-all"] .tbl tr,
  .page-view[data-view="users-all"] .tbl td{ display:block; }
  .page-view[data-view="users-all"] .tbl thead{ display:none; }
  .page-view[data-view="users-all"] .tbl .hide-sm{ display:flex; }
  .page-view[data-view="users-all"] .tbl tbody tr{
    position:relative;
    border:1px solid var(--border);border-radius:var(--mk-radius-lg);
    background:var(--bg-1);padding:12px 14px;margin-bottom:10px;
  }
  .page-view[data-view="users-all"] .tbl tbody tr:last-child{ margin-bottom:0; }
  .page-view[data-view="users-all"] .tbl tbody td{
    border:0;padding:6px 0;
    display:flex;align-items:center;justify-content:space-between;gap:14px;
    text-align:start;
  }
  .page-view[data-view="users-all"] .tbl td[data-col="member"]{
    padding:0 0 10px;margin-bottom:8px;
    border-bottom:1px solid var(--divider);
    padding-inline-end:34px; /* clear the pinned action affordance */
  }
  .page-view[data-view="users-all"] .tbl td[data-label]::before{
    content:attr(data-label);flex-shrink:0;
    font:600 11px var(--mk-font-ui);letter-spacing:.02em;color:var(--fg-3);
  }
  .page-view[data-view="users-all"] .tbl td.num{ font-variant-numeric:tabular-nums; }
  .page-view[data-view="users-all"] .tbl td.row-act{
    position:absolute;top:12px;inset-inline-end:12px;
    padding:0;width:auto;
  }
}
.role-badge{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 10px;border-radius:var(--mk-radius-pill);
  font:600 11px var(--mk-font-ui);
  background:var(--bg-3);color:var(--fg-2);
}
.role-badge.admin{ color:var(--accent-text);
  background:color-mix(in srgb,var(--accent) 12%,transparent); }
.role-badge.owner{ color:#A855F7;
  background:color-mix(in srgb,#A855F7 14%,transparent); }

/* ═══ USERS · ROLES (cards) ══════════════════════════════════════════ */
.role-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr));gap:14px; }
.role-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);padding:18px;
  display:flex;flex-direction:column;gap:14px;cursor:pointer;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast);
}
.role-card:hover{ border-color:var(--fg-3);box-shadow:var(--shadow-sm); }
.role-card .rc-h{ display:flex;align-items:center;gap:10px; }
.role-card .rc-ic{
  width:38px;height:38px;border-radius:11px;display:inline-flex;
  align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-text);
}
.role-card .rc-nm{ font:700 15px var(--mk-font-ui);color:var(--fg-1); }
.role-card .rc-sub{ font:500 12px var(--mk-font-ui);color:var(--fg-3); }
.role-card .rc-perms{ display:flex;flex-direction:column;gap:8px; }
.role-card .rc-perm{ display:flex;align-items:center;gap:8px;
  font:500 12px var(--mk-font-ui);color:var(--fg-2); }
.role-card .rc-perm .mi{ font-size:16px;color:var(--mk-success); }
.role-card .rc-perm.no .mi{ color:var(--fg-3); }
.role-card .rc-foot{ display:flex;align-items:center;justify-content:space-between;
  padding-top:12px;border-top:1px solid var(--divider); }
.role-card .rc-members{ display:flex;align-items:center; }
.role-card .rc-members .av{ margin-inline-start:-8px;border:2px solid var(--bg-1); }
.role-card .rc-members .av:first-child{ margin-inline-start:0; }
.role-card .rc-more{ font:600 12px var(--mk-font-ui);color:var(--fg-3);margin-inline-start:8px; }

/* ═══ CHAT (conversation list + slide-in thread panel) ═══════════════
   Pablo 2026-06-19: clicking a conversation opens the thread as a slide-in
   side panel (like the Filters panel), at EVERY breakpoint. The list fills
   the page; the thread slides in from the inline-end over a scrim. */
/* Desktop (default): two-pane master–detail. The conversation list sits
   beside a PERSISTENT thread pane showing the currently-selected chat
   (Pablo 2026-06-19 — "on desktop I should always see the chat window of
   the selected conversation"). At ≤1000px (tablet↓) this collapses to a
   single-pane list with the thread sliding in as a side panel. */
.chat{
  flex:1 1 0;min-height:0;position:relative;
  display:grid;grid-template-columns:300px minmax(0,1fr);gap:12px;
}
/* Chat is a space-hungry layout, so it bleeds to the edges more than other
   section views — Pablo 2026-06-21 (3×): "remove the gutter and padding
   entirely … left side messages, right side the selected conversation."
   Desktop ≥1001px: a true flush 2-pane — no page gutter/padding at all, no
   gap, the list and thread separated by a single divider, no card rounding
   (the body's own rounded corner + overflow clip the outer edges). */
@media (min-width:1001px){
  .page-view[data-view="chat"] .page{ padding:0; }
  .page-view[data-view="chat"] .page > .chat{ padding:0;gap:0; }
  .page-view[data-view="chat"] .chat-list{
    border-width:0;border-inline-end:1px solid var(--border);border-radius:0;
  }
  .page-view[data-view="chat"] .chat-thread{ border:0;border-radius:0; }
}
.chat-list{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);display:flex;flex-direction:column;
  min-height:0;overflow:hidden;flex:1;
}
.chat-list-h{ padding:14px 16px;border-bottom:1px solid var(--divider);
  display:flex;align-items:center;justify-content:space-between; }
.chat-list-h .t{ font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.chat-list-h .mi{ color:var(--fg-3);cursor:pointer; }
.chat-search{ margin:12px;display:flex;align-items:center;gap:8px;
  padding:8px 12px;background:var(--bg-2);border:1px solid var(--border);
  border-radius:var(--mk-radius-pill);color:var(--fg-3); }
.chat-search .mi{ font-size:18px; }
.chat-search input{ border:0;background:transparent;outline:0;flex:1;
  font:500 13px var(--mk-font-ui);color:var(--fg-1); }
.chat-convs{ overflow-y:auto;min-height:0;flex:1;padding:0 8px 8px; }
.chat-conv{
  display:flex;gap:10px;padding:8px;border-radius:var(--mk-radius-md);
  cursor:pointer;transition:background var(--mk-t-fast);align-items:center;
}
.chat-conv:hover{ background:var(--bg-2); }
.chat-conv.on{ background:color-mix(in srgb,var(--accent) 10%,transparent); }
.chat-conv .cc-main{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px; }
.chat-conv .cc-top{ display:flex;align-items:baseline;justify-content:space-between;gap:8px; }
.chat-conv .cc-nm{ font:600 13px var(--mk-font-ui);color:var(--fg-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.chat-conv .cc-tm{ font:500 11px var(--mk-font-ui);color:var(--fg-3);flex:0 0 auto; }
.chat-conv .cc-msg{ font:500 12px var(--mk-font-ui);color:var(--fg-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.chat-conv .cc-badge{ flex:0 0 auto;min-width:18px;height:18px;padding:0 5px;
  border-radius:var(--mk-radius-pill);background:var(--accent);color:#fff;
  font:700 10px var(--mk-font-ui);display:inline-flex;align-items:center;justify-content:center; }

.chat-thread{
  position:relative;width:auto;
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);display:flex;flex-direction:column;
  min-height:0;overflow:hidden;
}
/* Scrim + back button only matter in the single-pane (slide-in) layout. */
.chat-scrim{ display:none; }
.ct-h{ padding:10px 14px;border-bottom:1px solid var(--divider);
  display:flex;align-items:center;gap:10px; }
.ct-h .ct-nm{ font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.ct-h .ct-sub{ font:500 11px var(--mk-font-ui);color:var(--mk-success); }
.ct-h .ct-actions{ margin-inline-start:auto;display:flex;gap:2px;color:var(--fg-3); }
/* B63-145 — the identity block (avatar + name/sub) is now a real button that
   opens the person's/group's panel, same destination the "i" icon opens. */
.ct-h .ct-id{ display:flex;align-items:center;gap:10px;border:0;background:transparent;
  padding:2px 4px 2px 2px;margin-inline-start:-2px;border-radius:9px;cursor:pointer;text-align:start;min-width:0; }
.ct-h .ct-id:hover{ background:var(--bg-2); }
.ct-h .ct-id > div{ min-width:0; }
.ct-h .ct-id .ct-nm,.ct-h .ct-id .ct-sub{ overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
/* in-thread search bar */
.ct-search{ display:flex;align-items:center;gap:8px;padding:8px 14px;border-bottom:1px solid var(--divider);
  background:var(--bg-1); }
.ct-search > .mi{ font-size:18px;color:var(--fg-3); }
.ct-search input{ flex:1;min-width:0;height:30px;border:0;background:transparent;outline:none;
  font:500 13px var(--mk-font-ui);color:var(--fg-1); }
.ct-search-n{ font:600 11px var(--mk-font-ui);color:var(--fg-3);white-space:nowrap; }
mark.ct-hit{ background:color-mix(in srgb,var(--accent) 30%,transparent);color:inherit;border-radius:3px;padding:0 1px; }
mark.ct-hit.ct-hit-active{ background:var(--accent);color:var(--accent-fg,#fff); }
.ct-act{ border:0;background:transparent;color:var(--fg-3);cursor:pointer;width:36px;height:36px;border-radius:9px;
  display:inline-flex;align-items:center;justify-content:center;transition:background var(--mk-t-fast),color var(--mk-t-fast); }
.ct-act:hover{ background:var(--bg-2);color:var(--fg-1); }
.ct-act .mi{ font-size:20px; }
.ct-back{ display:none;border:0;background:transparent;cursor:pointer;color:var(--fg-2);
  width:34px;height:34px;border-radius:9px;align-items:center;justify-content:center;flex:0 0 auto;
  transition:background var(--mk-t-fast); }
.ct-back:hover{ background:var(--bg-2); }
.ct-body{ flex:1;min-height:0;overflow-y:auto;padding:12px 14px;
  display:flex;flex-direction:column;gap:8px; }
/* B63-048 — a chat conversation embedded as a wallet-panel slide (trip chat):
   same bubble list as the real Chat section, laid out in the slide's own
   (already-scrolling) body — same grammar the ticket panel's `tk-thread` +
   `tk-composer` pair uses for its embedded discussion. */
.wl-chat-slide{ display:flex;flex-direction:column;gap:8px }
.wl-chat-msgs{ display:flex;flex-direction:column;gap:8px }
.wl-chat-composer{ margin-top:8px;padding-top:10px;border-top:1px solid var(--border);position:sticky;bottom:-20px;background:var(--bg-1) }
.ct-day{ align-self:center;font:600 11px var(--mk-font-ui);color:var(--fg-3);
  background:var(--bg-2);padding:3px 12px;border-radius:var(--mk-radius-pill); }
.msg{ display:flex;gap:10px;max-width:82%; }
/* ═══ B51-29 · SWIPE / DOUBLE-TAP TO REPLY ════════════════════════
   Pablo: "Double tapping on a message row should auto default to responding to the
   message, same as swiping the message bubble like it works on whatsapp."
   The row translates by `--sw` (set live by the pointer handler) and a reply glyph
   is revealed behind it, fading in with the travel — the WhatsApp feel. `--sw` is
   only ever set while a swipe is in flight, so the row costs nothing at rest. */
.msg{ position:relative;--sw:0px; }
.msg.swiping{ transform:translateX(calc(var(--sw) * -1)); }
[dir="rtl"] .msg.swiping{ transform:translateX(var(--sw)); }
.msg.me.swiping{ transform:translateX(var(--sw)); }
[dir="rtl"] .msg.me.swiping{ transform:translateX(calc(var(--sw) * -1)); }
.msg::after{
  content:"reply";content:"reply" / "";font-family:'Material Symbols Rounded';font-size:18px;
  position:absolute;top:50%;inset-inline-end:-30px;transform:translateY(-50%) scale(.7);
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:var(--bg-2);color:var(--fg-3);opacity:0;pointer-events:none;
  transition:opacity var(--mk-t-fast),transform var(--mk-t-fast); }
.msg.me::after{ inset-inline-end:auto;inset-inline-start:-30px; }
.msg.swiping::after{ opacity:calc(var(--sw) / 52);transform:translateY(-50%) scale(.85); }
.msg.swipe-armed::after{ opacity:1;transform:translateY(-50%) scale(1);
  background:var(--accent);color:#fff; }
/* the confirmation blink when either gesture fires */
.msg.reply-flash .mb{ animation:msgReplyFlash .32s var(--mk-ease,ease-out); }
/* B65 W11 (065-069) — the original a quote led to, held long enough to see */
.mb-quote[data-q-mid]{ cursor:pointer } .mb-quote{ cursor:pointer }
.mb-quote:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.msg.quote-jump .mb{ animation:msgQuoteJump 1.6s var(--mk-ease,ease-out); }
@keyframes msgQuoteJump{ 0%,35%{ box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 70%,transparent),0 0 0 9px color-mix(in srgb,var(--accent) 22%,transparent) }
  100%{ box-shadow:0 0 0 0 transparent } }
@keyframes msgReplyFlash{ 0%{ box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 55%,transparent) }
  100%{ box-shadow:0 0 0 7px transparent } }
/* A swipe must own the horizontal axis or the thread scrolls instead. */
.ct-body .msg,.ts-body .msg{ touch-action:pan-y; }
.msg .mb{ padding:9px 13px;border-radius:14px;font:500 13px var(--mk-font-ui);
  line-height:1.5;color:var(--fg-1);background:var(--bg-2);
  border:1px solid var(--border);border-start-start-radius:4px; }
.msg .mt{ font:500 10px var(--mk-font-ui);color:var(--fg-3);margin-top:4px; }
.msg.me{ margin-inline-start:auto;flex-direction:row-reverse; }
.msg.me .mb{ background:var(--accent);color:#fff;border-color:transparent;
  border-start-start-radius:14px;border-start-end-radius:4px; }
.msg.me .mt{ text-align:end; }
/* typing indicator */
.msg.typing .mb{ padding:11px 14px; }
.typing-dots{ display:inline-flex;gap:4px;align-items:center; }
.typing-dots i{ width:6px;height:6px;border-radius:50%;background:var(--fg-3);display:inline-block; }
@media (prefers-reduced-motion:no-preference){
  .typing-dots i{ animation:typingBlink 1.2s var(--mk-ease) infinite; }
  .typing-dots i:nth-child(2){ animation-delay:.18s; }
  .typing-dots i:nth-child(3){ animation-delay:.36s; }
}
@keyframes typingBlink{ 0%,60%,100%{ opacity:.3;transform:translateY(0); } 30%{ opacity:1;transform:translateY(-2px); } }
.composer{ padding:8px 12px;border-top:1px solid var(--divider);
  display:flex;align-items:center;gap:10px; }
.composer .cmp-in{ flex:1;display:flex;align-items:center;gap:8px;
  background:var(--bg-2);border:1px solid var(--border);border-radius:var(--mk-radius-pill);
  padding:8px 14px; }
.composer .cmp-in input{ border:0;background:transparent;outline:0;flex:1;
  font:500 13px var(--mk-font-ui);color:var(--fg-1); }
.composer .cmp-in .mi{ color:var(--fg-3);cursor:pointer; }
.composer .send{ width:40px;height:40px;border-radius:50%;border:0;cursor:pointer;
  background:var(--accent);color:#fff;display:inline-flex;align-items:center;justify-content:center; }

/* ── chat: message column + hover actions + reactions + threads ──── */
.msg .msg-col{ display:flex;flex-direction:column;gap:4px;min-width:0;position:relative; }
.msg.me .msg-col{ align-items:flex-end; }
.msg-who{ font:700 11px var(--mk-font-ui);color:var(--fg-2);margin-bottom:1px; }
.msg .mb{ position:relative; }
.mb b,.mb strong{ font-weight:700; } .mb u{ text-decoration:underline; } .mb s,.mb strike{ text-decoration:line-through; }
.mb ul{ margin:4px 0;padding-inline-start:18px; } .mb li{ margin:1px 0; }
/* C15 (Pablo 2026-07-01) — render the full rich markup set in the bubble. */
.mb ol{ margin:4px 0;padding-inline-start:20px; }
.mb code{ font-family:var(--mk-font-ui);background:color-mix(in srgb,var(--fg-1) 8%,transparent);
  border:1px solid var(--border);border-radius:5px;padding:0 5px;font-size:.92em; }
.mb pre{ font-family:var(--mk-font-ui);background:color-mix(in srgb,var(--fg-1) 8%,transparent);
  border:1px solid var(--border);border-radius:8px;padding:8px 10px;margin:6px 0;
  white-space:pre-wrap;overflow:auto;font-size:.92em; }
.mb pre code{ background:transparent;border:0;padding:0; }
.mb blockquote{ margin:5px 0;padding:2px 10px;border-inline-start:3px solid color-mix(in srgb,var(--accent) 55%,transparent);color:var(--fg-2); }
.mb a{ color:var(--accent-text);text-decoration:underline; }
/* Accent (me) bubble has white text — give the rich elements contrast on it. */
.msg.me .mb code,.msg.me .mb pre{ background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.32);color:#fff; }
.msg.me .mb blockquote{ border-inline-start-color:rgba(255,255,255,.6);color:rgba(255,255,255,.88); }
.msg.me .mb a{ color:#fff; }
/* C16 — active formatting button (code-block etc.) */
.fmt-btn.active{ color:var(--accent);background:color-mix(in srgb, var(--accent) 14%, transparent); }
.mb-quote{ display:flex;flex-direction:column;gap:1px;border-inline-start:3px solid color-mix(in srgb,var(--accent) 55%,transparent);
  padding:3px 9px;margin-bottom:5px;border-radius:6px;background:color-mix(in srgb,var(--fg-1) 5%,transparent); }
.mb-quote b{ font:700 11px var(--mk-font-ui); } .mb-quote span{ font:500 11.5px var(--mk-font-ui);opacity:.75;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px; }
.msg.me .mb-quote{ background:rgba(255,255,255,.16);border-inline-start-color:rgba(255,255,255,.6); }
.mb-att{ margin-top:2px; }
/* faux screenshot tile */
.shot-thumb{ width:180px;border:1px solid var(--border);border-radius:10px;overflow:hidden;background:var(--bg-1); }
.shot-thumb.mini{ width:120px; }
.st-bar{ height:14px;display:flex;align-items:center;gap:4px;padding:0 7px;background:var(--bg-3); }
.st-bar i{ width:5px;height:5px;border-radius:50%;background:var(--fg-3);opacity:.5; }
.st-body{ padding:10px;display:flex;flex-direction:column;gap:6px;background:linear-gradient(160deg,color-mix(in srgb,var(--accent) 14%,var(--bg-2)),var(--bg-2)); }
.st-body span{ height:6px;border-radius:3px;background:var(--fg-3);opacity:.4; }
.st-l1{ width:70%; } .st-l2{ width:90%; } .st-l3{ width:50%; }
.st-card{ height:34px;border-radius:6px;background:color-mix(in srgb,var(--accent) 22%,var(--bg-1));margin-top:2px; }
.msg-acts{ position:absolute;top:-14px;inset-inline-end:0;display:flex;gap:2px;padding:2px;
  background:var(--bg-1);border:1px solid var(--border);border-radius:var(--mk-radius-pill);
  box-shadow:var(--mk-shadow-sm);opacity:0;visibility:hidden;transform:translateY(3px);
  transition:opacity var(--mk-t-fast),transform var(--mk-t-fast);z-index:4; }
/* B64 S1 — the bar grows toward the free side of the thread: from a received
   message's start edge inward, from your own message's end edge inward. With
   Forward/Edit/Delete it is six buttons wide; anchored the other way it ran off
   the screen on a phone. */
.msg:not(.me) .msg-acts{ inset-inline-end:auto;inset-inline-start:0; }
.msg.me .msg-acts{ inset-inline-start:auto;inset-inline-end:0; }
.msg:hover .msg-acts{ opacity:1;visibility:visible;transform:none; }
.ma-btn{ width:26px;height:26px;border:0;background:transparent;border-radius:50%;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;color:var(--fg-2); }
.ma-btn .mi{ font-size:17px; }
.ma-btn:hover{ background:var(--bg-2);color:var(--accent); }
/* B63-138 — thread badge + reactions sit on ONE inline row, thread first (to
   the left). `.msg-meta` is the shared row; `.msg-rx` no longer forces its
   own block/line since it can now be alone (no thread) or share the row. */
.msg-meta{ display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:2px; }
.msg-rx{ display:inline-flex;flex-wrap:wrap;gap:4px; }
.rx-chip{ display:inline-flex;align-items:center;gap:3px;font:600 11px var(--mk-font-ui);
  padding:1px 8px;border-radius:var(--mk-radius-pill);border:1px solid var(--border);
  background:var(--bg-1);color:var(--fg-2);cursor:pointer;line-height:1.7; }
.rx-chip.mine{ border-color:color-mix(in srgb,var(--accent) 55%,transparent);
  background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent); }
.rx-chip:hover{ border-color:var(--accent); }
.msg-thr{ display:inline-flex;align-items:center;gap:6px;padding:3px 8px 3px 4px;
  border:1px solid var(--border);border-radius:var(--mk-radius-pill);background:var(--bg-1);
  cursor:pointer;font:600 11.5px var(--mk-font-ui);color:var(--accent);max-width:max-content; }
.msg-thr:hover{ background:var(--bg-2); }
.msg-thr .thr-faces{ display:inline-flex; } .msg-thr .thr-faces .av{ margin-inline-end:-6px;border:1.5px solid var(--bg-1); }
.msg-thr .mi{ font-size:15px;color:var(--fg-3);margin-inline-start:auto; }

/* thread slide stack (unlimited nesting) */
.chat-thread{ overflow:hidden; }
.thread-slide{ position:absolute;inset:0;z-index:30;display:flex;flex-direction:column;
  background:var(--bg-1);transform:translateX(100%);transition:transform var(--mk-t-base) var(--mk-ease); }
html[dir="rtl"] .thread-slide{ transform:translateX(-100%); }
.thread-slide.in{ transform:none; }
html[dir="rtl"] .thread-slide.in{ transform:none; } /* Audit A11 — same RTL specificity trap as .ent-slide-pushed */
.ts-h{ flex:none;display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--divider);background:var(--bg-1); }
.ts-back{ width:30px;height:30px;border:0;border-radius:50%;background:transparent;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;color:var(--fg-2); }
.ts-back:hover{ background:var(--bg-2); }
.ts-title .ts-t{ font:700 13px var(--mk-font-ui);color:var(--fg-1); }
.ts-title .ts-sub{ font:500 11px var(--mk-font-ui);color:var(--fg-3); }
.ts-body{ flex:1;min-height:0;overflow-y:auto;padding:12px 14px;display:flex;flex-direction:column;gap:8px; }
.ts-parent{ background:var(--bg-2);border:1px solid var(--border);border-radius:12px;padding:10px 12px;max-width:100%;gap:10px; }
.ts-parent .msg-col{ align-items:flex-start; }
.ts-parent .mb{ background:transparent;border:0;padding:0; }
.ts-divider{ display:flex;align-items:center;gap:10px;color:var(--fg-3);font:600 11px var(--mk-font-ui); }
.ts-divider::before,.ts-divider::after{ content:"";flex:1;height:1px;background:var(--divider); }

/* rich composer */
.composer{ flex-direction:column;align-items:stretch;gap:8px; }
.cmp-row{ display:flex;align-items:flex-end;gap:10px; }
.composer .cmp-in{ flex:1;align-items:flex-end; }
.cmp-edit{ flex:1;min-height:20px;max-height:120px;overflow-y:auto;outline:0;
  font:500 13px var(--mk-font-ui);color:var(--fg-1);line-height:1.5;word-break:break-word; }
.cmp-edit:empty::before{ content:attr(data-ph);color:var(--fg-3);pointer-events:none; }
.cmp-ico{ border:0;background:transparent;cursor:pointer;color:var(--fg-3);padding:0;flex:none;
  display:inline-flex;align-items:center;height:20px; }
.cmp-ico:hover{ color:var(--accent); }
.cmp-fmt{ display:flex;align-items:center;gap:1px;flex-wrap:wrap;align-self:stretch;
  padding:1px 2px 3px;border-bottom:1px solid var(--divider);margin-bottom:1px; }
.cmp-fmt[hidden]{ display:none; }
.fmt-btn{ width:28px;height:28px;border:0;border-radius:6px;background:transparent;cursor:pointer;
  color:var(--fg-2);display:inline-flex;align-items:center;justify-content:center; }
.fmt-btn .mi{ font-size:18px; } .fmt-btn:hover{ background:var(--bg-2);color:var(--accent); }
.cmp-attach-row{ display:flex;gap:8px;flex-wrap:wrap; }
.cmp-attach-row[hidden]{ display:none; }
.cmp-att{ position:relative; }
.cmp-att .att-x{ position:absolute;top:-6px;inset-inline-end:-6px;width:20px;height:20px;border-radius:50%;
  border:0;background:var(--fg-1);color:var(--bg-1);cursor:pointer;display:inline-flex;align-items:center;justify-content:center; }
.cmp-att .att-x .mi{ font-size:13px; }
.cmp-att.loading .shot-thumb{ animation:shotPulse 1s ease-in-out infinite; }
.cmp-att.loading .att-x{ display:none; }
.cmp-att .att-prog{ position:absolute;left:0;right:0;bottom:0;height:3px;border-radius:3px;background:var(--bg-3);overflow:hidden; }
.cmp-att.loading .att-prog::after{ content:"";position:absolute;inset:0;width:40%;background:var(--accent);
  border-radius:3px;animation:shotProg 1.6s ease forwards; }
.cmp-att:not(.loading) .att-prog{ display:none; }
/* B29 C9 — all-file attachment chips (name + thumb/icon) */
.cmp-att{ display:flex;align-items:center;gap:8px;max-width:230px;padding:6px 9px;
  border:1px solid var(--border);border-radius:10px;background:var(--bg-1); }
.cmp-att-thumb{ width:26px;height:26px;border-radius:7px;flex:0 0 auto;background-size:cover;
  background-position:center;display:grid;place-items:center;background-color:var(--accent-soft);color:var(--accent-text); }
.cmp-att-thumb.file .mi{ font-size:16px; }
.cmp-att-nm{ font:600 11.5px var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:text; }
.cmp-att-nm:hover{ color:var(--fg-1);text-decoration:underline dotted; }
.cmp-att-nm-inp{ font:600 11.5px var(--mk-font-ui);color:var(--fg-1);border:0;background:transparent;outline:0;width:8ch;min-width:40px;max-width:120px;padding:0; }
.cmp-att-ext{ font:600 11.5px var(--mk-font-ui);color:var(--fg-3); }
.cmp-att.loading .cmp-att-thumb{ animation:shotPulse 1s ease-in-out infinite; }
@keyframes shotPulse{ 0%,100%{ opacity:1; } 50%{ opacity:.45; } }
@keyframes shotProg{ from{ transform:translateX(-100%); } to{ transform:translateX(250%); } }
.cmp-quote{ display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:var(--mk-radius-md);
  background:var(--bg-2);border-inline-start:3px solid var(--accent); }
.cmp-quote .mi{ color:var(--accent);font-size:18px; }
.cmp-quote .cq-main{ flex:1;min-width:0;display:flex;flex-direction:column; }
.cmp-quote .cq-main b{ font:700 11px var(--mk-font-ui); }
.cmp-quote .cq-main span{ font:500 12px var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.cmp-quote .cq-x{ border:0;background:transparent;cursor:pointer;color:var(--fg-3);display:inline-flex; }

/* emoji popover (floats above everything) */
.emoji-pop{ position:fixed;z-index:9999;background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-md);box-shadow:var(--mk-shadow-lg);padding:6px; }
.emoji-pop .ep-quick{ display:flex;gap:2px;align-items:center; }
.emoji-pop button{ width:32px;height:32px;border:0;background:transparent;border-radius:8px;cursor:pointer;
  font-size:19px;display:inline-flex;align-items:center;justify-content:center; }
.emoji-pop button:hover{ background:var(--bg-2); }
.emoji-pop .ep-more .mi{ font-size:18px;color:var(--fg-3); }
.emoji-pop .ep-grid{ display:grid;grid-template-columns:repeat(6,32px);gap:2px;max-height:200px;overflow-y:auto; }
.emoji-pop .ep-grid[hidden]{ display:none; }

/* B54 — MARKETPLACE REMOVED (Pablo: "this menu item is just wasting code").
   The whole `.mkt-*` family went with the route — except `.mkt-ic`, which the
   deployment and permission DRAWERS still use as their hero tile. */
.mkt-ic{ width:46px;height:46px;border-radius:13px;flex:0 0 auto;
  display:grid;place-items:center;color:#fff; }
.mkt-ic .mi{ font-size:23px; }

/* ═══ SCHEDULE · TODAY (agenda) ══════════════════════════════════════ */
/* ═══ SCHEDULE · TODAY (proportional agenda) ═════════════════════════ */
/* A continuous time axis: every half-hour is the SAME vertical distance and
   each event's height reflects its real duration (56px/hour). Hour labels sit
   in the axis column; hour + half-hour gridlines are painted as a repeating
   background on the track so a 30-min block reads as half a 60-min block. */
.agenda{ min-width:0; }  /* B65 W12 (065-098) — the Day view takes the whole content width again */
.agenda-grid{ display:grid;grid-template-columns:56px 1fr;gap:0; }
.ag-axis{ position:relative; }
.ag-track{
  position:relative;border-inline-start:1px solid var(--divider);
  background-image:
    repeating-linear-gradient(to bottom, var(--divider) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(to bottom, transparent 0 28px,
      color-mix(in srgb,var(--divider) 50%,transparent) 28px 29px, transparent 29px 56px);
}
.ag-time{ position:absolute;inset-inline-end:10px;transform:translateY(-50%);
  font:600 11px var(--mk-font-ui);color:var(--fg-3);
  font-variant-numeric:tabular-nums;text-align:end;white-space:nowrap; }
.ag-event{
  position:absolute;inset-inline:8px 0;
  box-sizing:border-box;overflow:hidden;
  border-radius:var(--mk-radius-md);padding:6px 10px;
  border-inline-start:3px solid var(--accent);
  background:color-mix(in srgb,var(--accent) 12%,var(--bg-1));
  cursor:pointer;display:flex;flex-direction:row;align-items:center;gap:8px;
  transition:transform var(--mk-t-fast),box-shadow var(--mk-t-fast);
}
.ag-event:hover{ transform:translateX(2px);box-shadow:var(--shadow-sm);z-index:2; }
.ag-event{ cursor:grab;touch-action:none; }
.ag-event.ag-event-dragging{ cursor:grabbing;box-shadow:var(--shadow-md);z-index:5;opacity:.92;transform:none; }
/* Top/bottom resize handles — drag to change the event's start or end time
   (Pablo 2026-06-21: "stretch them from the top or bottom to extend the
   event's duration"). Invisible strips that show a row-resize cursor; a thin
   accent grip appears on hover. */
.ae-resize{ position:absolute;inset-inline:0;height:9px;cursor:ns-resize;z-index:6;touch-action:none; }
.ae-resize-t{ top:-2px; }
.ae-resize-b{ bottom:-2px; }
.ae-resize::after{ content:"";position:absolute;inset-inline:38% 38%;height:3px;border-radius:2px;
  background:currentColor;opacity:0;transition:opacity var(--mk-t-fast); }
.ae-resize-t::after{ top:3px; }
.ae-resize-b::after{ bottom:3px; }
.ag-event:hover .ae-resize::after{ opacity:.5; }
/* Text block: takes remaining width and TRUNCATES; avatars sit on the right
   so a short event doesn't waste vertical space (Pablo 2026-06-21). */
.ag-event .ae-main{ flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px;justify-content:center; }
.ag-event .ae-t{ font:600 13px var(--mk-font-ui);color:var(--fg-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.ag-event .ae-m{ font:500 12px var(--mk-font-ui);color:var(--fg-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
/* Short events (<1h): hide the meta line; title + avatars stay on one row. */
.ag-event.is-compact{ padding:3px 10px; }
.ag-event.is-compact .ae-m{ display:none; }
/* B50-22 — Day view: same corner treatment. The bubbles were vertically centred
   beside the text; Pablo wants them in the bottom-inline-end corner in Day as
   well as Week. They keep their own column (so they never cover the text) and
   simply sit at its end. */
.ag-event .ae-people{ align-self:flex-end;padding-bottom:1px; }
.ag-event.is-compact .ae-people{ align-self:center;padding-bottom:0; }
.ag-event.g{ border-inline-start-color:var(--mk-success);
  background:color-mix(in srgb,var(--mk-success) 10%,var(--bg-1)); }
.ag-event.p{ border-inline-start-color:#A855F7;
  background:color-mix(in srgb,#A855F7 10%,var(--bg-1)); }
.ag-event .ae-people{ display:flex;align-items:center;flex:0 0 auto; }
.ag-event .ae-people .av{ margin-inline-start:-7px;border:2px solid var(--bg-1); }
.ag-event .ae-people .av:first-child{ margin-inline-start:0; }

/* ═══ SERVICES · BACKEND (health cards) ══════════════════════════════ */
.svc-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr));gap:14px; }
.svc-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);padding:18px;
  display:flex;flex-direction:column;gap:14px;cursor:pointer;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast);
}
.svc-card:hover{ border-color:var(--fg-3);box-shadow:var(--shadow-sm); }
.svc-h{ display:flex;align-items:center;gap:10px; }
.svc-h .svc-nm{ font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.svc-h .svc-env{ font:500 11px var(--mk-font-mono);color:var(--fg-3); }
.svc-h .pill{ margin-inline-start:auto; }
.svc-metrics{ display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px; }
.svc-metric{ display:flex;flex-direction:column;gap:3px; }
.svc-metric .sm-l{ font:600 10px var(--mk-font-ui);letter-spacing:.03em;
  text-transform:none;color:var(--fg-3); }
.svc-metric .sm-v{ font:700 16px var(--mk-font-ui);color:var(--fg-1);
  font-variant-numeric:tabular-nums; }
.svc-spark{ display:flex;align-items:flex-end;gap:3px;height:36px; }
.svc-spark i{ flex:1;background:color-mix(in srgb,var(--accent) 32%,transparent);
  border-radius:2px 2px 0 0;min-height:3px; }
.svc-spark i.peak{ background:var(--accent); }
@media (prefers-reduced-motion:no-preference){
  .svc-spark.refreshed i{ animation:sparkGrow .5s var(--mk-ease) both; }
}
@keyframes sparkGrow{ from{ transform:scaleY(.2);opacity:.4; } to{ transform:scaleY(1);opacity:1; } }
.svc-spark i{ transform-origin:bottom; }

/* ═══ MAP (real Leaflet MapView component) ═══════════════════════════ */
/* The Map section mounts window.MkMapView (Components/MapView); the
   component supplies its own canvas + region list + chrome. We only give
   the mount room to fill the page (Pablo 2026-06-19 — "I want a serious
   prototype, like the components side"). */
.map-wrap{ display:flex;flex:1;min-height:0; }
.map-mount{ flex:1;min-height:420px;display:flex; }
.map-mount[hidden]{ display:none; }
.map-mount > .mk-map{ flex:1; }
/* Map Places/Zones tabs — header seg (Pablo B12 C14). */
.map-tabs{ margin-inline-start:auto; }
/* Chat composer markup (Pablo B12 C08/C15) — Slack-style toolbar + Aa toggle. */
.cmp-fmt-sep{ width:1px;height:18px;background:var(--divider);margin:0 4px;flex:0 0 auto; }
.cmp-ico[data-cmp-fmt-toggle].on{ color:var(--accent);background:color-mix(in srgb, var(--accent) 14%, transparent); }
.cmp-edit code{ font-family:var(--mk-font-ui);background:var(--bg-3);border:1px solid var(--border);border-radius:5px;padding:0 5px;font-size:.92em; }
.cmp-edit pre{ font-family:var(--mk-font-ui);background:var(--bg-3);border:1px solid var(--border);border-radius:8px;padding:8px 10px;margin:6px 0;white-space:pre-wrap;overflow:auto; }
.cmp-edit blockquote{ margin:6px 0;padding:2px 0 2px 12px;border-inline-start:3px solid var(--border-strong);color:var(--fg-2); }
.cmp-edit ol,.cmp-edit ul{ margin:6px 0;padding-inline-start:22px; }

/* Pablo B11-11: on tablet/mobile the map filled the whole .page (flex:1) and
   Leaflet swallowed every gesture, so the PAGE couldn't scroll. Size the map
   card to its CONTENT here (fixed-height canvas + natural-height region list)
   so .page overflows and scrolls — panning still works over the canvas, and
   scrolling over the header / region list / margins scrolls the page. Scoped
   to the app's map page so the Components-lab MapView preview is untouched. */
@media (max-width:600px) and (orientation:portrait),
       (min-width:601px) and (max-width:1024px) and (min-height:600px){
  /* B63-121 (Pablo: "the map should not move with the scroll, that's the
     point of the flex-col structure, that I can always see the map and still
     browse through the list elements") — reverses the "let .page grow to
     content" half of UI-59 below: .map-wrap/.map-mount now get a BOUNDED
     height (set via --mk-map-chrome further down) instead of sizing to
     content, so the canvas keeps its fixed half and the side list gets real,
     bounded room to flex into and scroll WITHIN — using map.css's own
     column-mode default (flex:1 1 auto + overflow-y:auto), which the old
     `.mk-map-side{flex:none}` / `.mk-map-side-list{overflow:visible}`
     overrides below used to defeat. Nothing here grows past the frame, so
     .page itself never needs to scroll either. */
  .page-view[data-view="map"] .map-wrap{ display:flex;min-height:0; }
  .page-view[data-view="map"] .map-mount{ display:flex;min-height:0; }
  .page-view[data-view="map"] .map-mount > .mk-map{ height:100%; }
  .page-view[data-view="map"] .mk-map-grid{ min-height:0; }
  /* B62 UI-59 (Pablo: "The map on mobile portrait is too tall — on tablet and
     mobile it should take exactly 50% of the available height, the list takes
     the other half… the map would still have a FIXED height of whatever height
     the frame has so there's no weird frame crop effect").
     58vh was neither half nor stable: `vh` ignores the mobile URL bar, and the
     navbar + bottom bar are not part of "available". Available height is the
     frame minus the chrome, and the canvas takes exactly half of it — a fixed
     px height at any moment, so the tiles never crop mid-frame. */
  .page-view[data-view="map"]{ --mk-map-chrome:calc(var(--mk-nav-h) + 96px); }
  /* The bottom bar is only real when the page HAS tabs (sections.css hides it
     otherwise) — subtracting it unconditionally stole 62px from a page that
     never shows it, and the canvas came out at 314px where half was 345. */
  .shell.signed-in.has-page-tabs .page-view[data-view="map"]{ --mk-map-chrome:calc(var(--mk-nav-h) + var(--mk-tabbar-h) + 96px); }
  .page-view[data-view="map"] .map-wrap{ height:calc(100dvh - var(--mk-map-chrome)); }
  .page-view[data-view="map"] .mk-map-canvas{ flex:none;height:calc((100dvh - var(--mk-map-chrome)) * .5);min-height:240px; }
}
/* B46 P6-ML03 — mobile LANDSCAPE hits neither branch above, so the map
   route kept the desktop 420px floor on a ~240px-tall screen: the canvas
   alone ran ~1.8 screens and the region list beside it was cut with it.
   The floor lives HERE on the mount (map.css can only shrink what the
   host lets it), so the fold-sized height has to be set here too. */
@media (max-height:599px) and (orientation:landscape){
  .page-view[data-view="map"] .map-mount{ min-height:0;height:min(420px, calc(100dvh - 96px)); }
  .page-view[data-view="map"] .mk-map-canvas{ min-height:0; }
  .page-view[data-view="map"] .mk-map-side-list{ max-height:none; }
}

/* ═══ SCHEDULE · WEEK (time grid) ════════════════════════════════════ */
/* Same gutter→margin conversion as .tbl-card: these bordered,
   overflow:hidden cards must INSET from the page edges so their own
   rounded corners show, instead of spanning to the rounded page edge and
   being clipped square against it (Pablo 2026-06-19 — "left/right cropped,
   weird against the rounded parent"). */
.sec-view .page > .wk-card,
.sec-view .page > .mo-card{ padding-inline:0;margin-inline:24px; }
.sec-view .page > .wk-card:last-child,
.sec-view .page > .mo-card:last-child{ margin-bottom:24px; }
.wk-card{
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);display:flex;flex-direction:column;
  /* C1 (Pablo 2026-07-01): the card is the SINGLE scroll container so the day
     header and the time grid scroll horizontally IN SYNC (they share the same
     column template); the header is pinned to the top vertically (sticky) while
     the times scroll under it. */
  overflow:auto;max-height:calc(100dvh - 210px);
}
.wk-head{ display:grid;grid-template-columns:56px repeat(7,minmax(0,1fr));
  border-bottom:1px solid var(--border);background:var(--bg-2);
  position:sticky;top:0;z-index:3; }
.wk-corner{ border-inline-end:1px solid var(--divider); }
.wk-day{ padding:10px 6px;text-align:center;border-inline-start:1px solid var(--divider);
  display:flex;flex-direction:column;gap:1px; }
.wk-day .wd-n{ font:600 11px var(--mk-font-ui);letter-spacing:.04em;text-transform:none;color:var(--fg-3); }
.wk-day .wd-d{ font:700 16px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wk-day.on .wd-n{ color:var(--accent-text); }
.wk-day.on .wd-d{ color:var(--accent-text); }
.wk-grid{ display:grid;grid-template-columns:56px repeat(7,minmax(0,1fr));
  min-height:0; }
/* B10-13 (Pablo): Week view — a header chip toggles weekdays-only (Mon–Fri).
   Default shows all 7; .wk-weekdays hides Sat/Sun and tightens to 5 columns. */
.wk-days-btn .wk-lbl-all{ display:none; }
.page-view.wk-weekdays .wk-days-btn .wk-lbl-wd{ display:none; }
.page-view.wk-weekdays .wk-days-btn .wk-lbl-all{ display:inline; }
.page-view.wk-weekdays .wk-head,
.page-view.wk-weekdays .wk-grid{ grid-template-columns:56px repeat(5,minmax(0,1fr)); }
.page-view.wk-weekdays .wk-head .wk-day:nth-child(n+7),
.page-view.wk-weekdays .wk-col[data-wk-col="5"],
.page-view.wk-weekdays .wk-col[data-wk-col="6"]{ display:none; }
.wk-times{ display:flex;flex-direction:column;border-inline-end:1px solid var(--divider); }
.wk-time{ font:600 10px var(--mk-font-ui);color:var(--fg-3);text-align:end;
  padding:2px 8px 0 0;box-sizing:border-box;border-top:1px solid transparent; }
.wk-col{ position:relative;border-inline-start:1px solid var(--divider);
  background-image:repeating-linear-gradient(to bottom,
    var(--divider) 0, var(--divider) 1px, transparent 1px, transparent 52px); }
.wk-col.on{ background-color:color-mix(in srgb,var(--accent) 4%,transparent); }
/* Day column highlighted while a week event is dragged over it (cross-date
   reschedule, Pablo 2026-06-22). */
.wk-col.wk-col-drop{ background-color:color-mix(in srgb,var(--accent) 9%,transparent);
  box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--accent) 35%,transparent); }
.wk-event{
  position:absolute;inset-inline:4px;border-radius:8px;padding:5px 8px;
  border-inline-start:3px solid var(--accent);overflow:hidden;cursor:pointer;
  background:color-mix(in srgb,var(--accent) 13%,var(--bg-1));
  display:flex;flex-direction:column;gap:1px;
  transition:filter var(--mk-t-fast); }
.wk-event:hover{ filter:brightness(1.04); }
.wk-event .we-t{ font:600 11px var(--mk-font-ui);color:var(--fg-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.wk-event .we-m{ font:500 10px var(--mk-font-ui);color:var(--fg-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
/* Short events: title takes priority — drop the (inferable) time line so the
   title is never clipped in favour of the clock. Pablo 2026-06-22. */
.wk-event.is-compact{ padding-top:3px;padding-bottom:3px; }
.wk-event.is-compact .we-m{ display:none; }
/* ── B50-22 — attendee bubbles in the bottom-inline-end corner ────────────────
   Pablo: "The user bubbles shouldn't cover all the text, and given this
   restriction maybe they should be placed on the bottom right corner of the event
   when in Daily or weekly truncation." They used to be an in-flow row pushed down
   with `margin-top:auto`, which on a short event consumed the line the title
   needed. Now they are pinned to the corner, and the text side RESERVES the space
   they occupy — either a bottom strip (tall enough for its own row) or an inline
   gutter on the last line (short events). Nothing ever overlaps. */
.wk-event .we-people{ position:absolute;inset-inline-end:6px;bottom:3px;margin:0;padding:0;z-index:1;
  display:flex;align-items:center;pointer-events:none; }
.wk-event.we-ppl-row{ padding-bottom:21px; }
.wk-event.we-ppl-inline .we-t,
.wk-event.we-ppl-inline .we-m{ padding-inline-end:38px; }
/* The stack itself: overlapping xs avatars, ringed so they read on any tint. */
.wk-event .we-people .av{ margin-inline-start:-6px;box-shadow:0 0 0 2px var(--bg-1); }
.wk-event .we-people .av:first-child{ margin-inline-start:0; }
.wk-event.g{ border-inline-start-color:var(--mk-success);
  background:color-mix(in srgb,var(--mk-success) 13%,var(--bg-1)); }
.wk-event.p{ border-inline-start-color:#A855F7;
  background:color-mix(in srgb,#A855F7 13%,var(--bg-1)); }
/* Week event drag-to-reschedule + top/bottom resize handles (Pablo 2026-06-21) */
.wk-event{ cursor:grab;touch-action:none; }
.wk-event.wk-event-dragging{ cursor:grabbing;z-index:5;box-shadow:var(--shadow-md);filter:brightness(1.05); }
.wk-ev-rz{ position:absolute;inset-inline:0;height:7px;cursor:ns-resize;z-index:2; }
.wk-ev-rz-t{ top:-1px; }
.wk-ev-rz-b{ bottom:-1px; }

/* ═══ SCHEDULE · MONTH (grid) ════════════════════════════════════════ */
.mo-card{ background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);overflow:hidden;display:flex;flex-direction:column;
  flex:1;min-height:0; }
.mo-head{ display:grid;grid-template-columns:repeat(7,1fr);background:var(--bg-2);
  border-bottom:1px solid var(--border); }
.mo-dow{ padding:10px 12px;font:600 11px var(--mk-font-ui);letter-spacing:.04em;
  text-transform:none;color:var(--fg-3);text-align:start; }
.mo-grid{ display:grid;grid-template-columns:repeat(7,1fr);
  grid-auto-rows:1fr;flex:1;min-height:0; }
.mo-cell{ border-inline-start:1px solid var(--divider);border-top:1px solid var(--divider);
  padding:8px;display:flex;flex-direction:column;gap:4px;min-height:96px;min-width:0;
  /* B54 — the chip drops its hour when the cell is too narrow to hold all three
     pieces (see .mo-ev-h). A CONTAINER query, because the deciding width is this
     cell's, not the viewport's: the same grid is narrower inside a preview frame
     or with the panel open. */
  container-type:inline-size;
  transition:background var(--mk-t-fast); }
.mo-cell:not(.dim){ cursor:pointer; }
.mo-cell:not(.dim):hover{ background:color-mix(in srgb, var(--accent) 5%, transparent); }
.mo-cell:nth-child(7n+1){ border-inline-start:0; }
.mo-cell.dim{ background:var(--bg-2); }
.mo-cell.dim .mo-date{ color:var(--fg-3); }
.mo-date{ font:600 13px var(--mk-font-ui);color:var(--fg-2);
  width:26px;height:26px;flex:none;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;
  font-variant-numeric:tabular-nums; }
/* B10-14 (Pablo): the today marker read as a squashed oval — the date span was
   shrinking vertically inside the flex-column cell (26×21.5). flex:none pins it
   to a true 26×26 circle. */
.mo-date.today{ background:var(--accent);color:#fff;border-radius:50%;font-weight:700; }
.mo-ev{ font:600 10.5px var(--mk-font-ui);color:var(--accent-text);
  background:color-mix(in srgb,var(--accent) 11%,transparent);
  border-radius:5px;padding:2px 7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
/* B54 — the chip carries the hour and the attendee bubbles now (Pablo: "it
   would be nice to see some avatar bubbles for the participants and … maybe the
   hour"). One row: hour, title (elastic), avatars pinned to the end. */
.mo-ev{ display:flex;align-items:center;gap:5px;min-width:0; }
.mo-ev-h{ flex:0 0 auto;font-weight:800;font-variant-numeric:tabular-nums;opacity:.8; }
/* Pablo's own priority order: the title matters, the attendee bubbles were the
   ask, and the hour was "I'm not sure how to fit it in" — so the hour is the
   first thing to go, and the title never collapses to an ellipsis stub. */
.mo-ev-t{ flex:1 1 auto;min-width:4.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
/* B67 R67-068 — in Arabic a Latin event title was ellipsized at its START ("…ketplace sync"): it takes its direction from its own
   text (R67-014), still right-aligned */
html[dir="rtl"] .mo-ev-t, html[dir="rtl"] .wk-event .we-tt, html[dir="rtl"] .ag-event .ae-tt{ unicode-bidi:plaintext; text-align:right; }
@container (max-width:132px){ .mo-ev-h{ display:none } }
@container (max-width:96px){ .mo-ev-ppl{ display:none } }
.mo-ev-ppl{ flex:0 0 auto;display:inline-flex;flex-direction:row-reverse; }
.mo-ev-ppl .av{ width:15px;height:15px;font-size:7px;margin-inline-start:-4px;border:1.5px solid var(--bg-1); }
/* B60 — the +n is a BUTTON now (it opens the day's full list), so it needs the
   button reset the span never did; and a chip trimmed by `moTrim()` must actually
   disappear, which `[hidden]` alone cannot do against `.mo-ev{display:flex}`. */
.mo-more{ font:700 9.5px var(--mk-font-ui);color:var(--fg-3);padding:2px 5px;margin-inline-start:-2px;
  border:0;background:transparent;border-radius:5px;cursor:pointer;align-self:flex-start;text-align:start; }
.mo-more:hover{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-text); }
.mo-ev[hidden],.mo-more[hidden]{ display:none !important; }
/* the day popover the +n opens: every event on that date, in time order */
.mo-pop{ position:fixed;z-index:9700;width:min(300px,92vw);max-height:min(60dvh,420px);
  display:flex;flex-direction:column;background:var(--bg-1);border:1px solid var(--border);
  border-radius:12px;box-shadow:var(--shadow-lg);overflow:hidden; }
.mo-pop-hd{ display:flex;align-items:center;gap:8px;padding:10px 8px 10px 12px;border-bottom:1px solid var(--divider); }
.mo-pop-hd b{ font:700 13px var(--mk-font-ui);color:var(--fg-1); }
.mo-pop-hd span{ font:600 11px var(--mk-font-ui);color:var(--fg-3); }
.mo-pop-x{ margin-inline-start:auto;width:28px;height:28px;border:0;border-radius:8px;background:transparent;
  color:var(--fg-2);cursor:pointer;display:inline-flex;align-items:center;justify-content:center; }
.mo-pop-x:hover{ background:var(--bg-2); }
.mo-pop-x .mi{ font-size:18px; }
.mo-pop-list{ overflow:auto;padding:6px;display:flex;flex-direction:column;gap:2px; }
.mo-pop-row{ display:flex;align-items:center;gap:9px;width:100%;padding:8px 9px;border:0;border-radius:9px;
  background:transparent;cursor:pointer;text-align:start;min-height:40px;
  border-inline-start:3px solid var(--accent); }
.mo-pop-row:hover{ background:color-mix(in srgb,var(--accent) 8%,transparent); }
.mo-pop-row.g{ border-inline-start-color:var(--mk-success); }
.mo-pop-row.p{ border-inline-start-color:#A855F7; }
.mo-pop-h{ flex:0 0 auto;font:700 11px var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums;min-width:38px; }
.mo-pop-t{ flex:1 1 auto;min-width:0;font:600 12.5px/1.35 var(--mk-font-ui);color:var(--fg-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.mo-pop-ppl{ flex:0 0 auto;display:inline-flex;flex-direction:row-reverse; }
.mo-pop-ppl .av{ width:17px;height:17px;font-size:8px;margin-inline-start:-5px;border:1.5px solid var(--bg-1); }
@media (pointer:coarse){ .mo-pop-row{ min-height:44px; } .mo-more{ min-height:24px; } }
/* the calendar flavour of the shared hover tooltip */
.tkt-tip.cal-tip .tkt-tip-h .dot{ width:8px;height:8px;border-radius:50%;display:inline-block; }
.tkt-tip.cal-tip .tkt-tip-v .av{ margin-inline-start:-5px; }
.tkt-tip .tkt-tip-more{ font:700 10px var(--mk-font-ui);color:var(--fg-3);margin-inline-start:5px; }
.mo-ev.g{ color:var(--mk-success);background:color-mix(in srgb,var(--mk-success) 12%,transparent); }
.mo-ev.p{ color:#A855F7;background:color-mix(in srgb,#A855F7 12%,transparent); }
/* Month chip drag-to-another-day (Pablo 2026-06-21) */
.mo-ev{ cursor:grab;touch-action:none; }
.mo-ev.mo-ev-dragging{ cursor:grabbing;opacity:.4;box-shadow:none; }
/* Floating ghost that follows the pointer during a month-chip drag (Pablo
   2026-06-22). Fixed to the viewport, non-interactive, slightly lifted. */
.mo-ev-ghost{ position:fixed;z-index:9999;pointer-events:none;margin:0;
  box-shadow:var(--shadow-md);transform:scale(1.04);opacity:.95; }
.mo-cell.mo-drop{ background:color-mix(in srgb,var(--accent) 13%,transparent);
  outline:2px dashed color-mix(in srgb,var(--accent) 45%,transparent);outline-offset:-2px; }
/* ══ B57 — the calendar in MOBILE LANDSCAPE ═══════════════════════════════
   Pablo: "On mobile landscape, the calendar views don't fit. A user should be able
   to access every item on a page in every screen."

   MEASURED at 667×375: the month grid needed 480px (five weeks × the 96px cell
   floor) inside a 219px window — and `.mo-card{overflow:hidden}` meant those three
   hidden weeks were not merely below the fold, they were UNREACHABLE: a touch drag
   had nothing to scroll. Two things follow. The card becomes a real scroller, and
   the grid buys back the ~32px of chrome it does not need at this height (page gap,
   card margins, the day-of-week strip) with a lower row floor, so about four weeks
   are in view at once and the fifth is one obvious drag away. */
@media (max-height:599px) and (orientation:landscape){
  .mo-card{ overflow-y:auto;overflow-x:hidden;scrollbar-width:thin; }
  .page-view[data-view="schedule-month"] .page,
  .page-view[data-view="schedule-week"] .page{ gap:10px; }
  .sec-view .page > .mo-card,
  .sec-view .page > .wk-card{ margin-inline:12px; }
  .sec-view .page > .mo-card:last-child,
  .sec-view .page > .wk-card:last-child{ margin-bottom:12px; }
  .mo-dow{ padding:5px 8px;font-size:10px; }
  .mo-cell{ min-height:64px;padding:5px;gap:3px; }
  .mo-date{ width:20px;height:20px;font-size:11px; }
  /* B62 UI-60 (Pablo: "there's a date with 4 meetings, they are very clumped
     together and I can't read anything. I think it's just better to show the first
     one and then "+{n}"") — `moCap()` shows ONE chip here now, so the chip can stop
     apologising for its width: it goes back up to a readable 11px, and the count
     that carries the rest of the day becomes a real chip-sized 24px target instead
     of 9.5px of grey text. */
  .mo-ev{ font-size:11px;padding:2px 5px;gap:4px; }
  .mo-more{ font-size:10.5px;padding:2px 6px;min-height:22px;
    background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent-text); }
  /* B60 (Pablo: "The weekly view calendar frame on mobile landscape is too short in
     height. Please fix it") — the base card is capped at `calc(100dvh - 210px)`,
     which is a DESKTOP budget: at 375px tall that left a 165px frame showing barely
     three hours. Here the card is simply the rest of the page — it takes the space
     the header and tabs leave and scrolls inside itself, exactly like .mo-card. */
  .wk-card{ max-height:none;flex:1 1 auto;min-height:210px; }
}

/* ═══ USERS · PERMISSIONS (matrix) ═══════════════════════════════════ */
.pm-leg{ display:inline-flex;align-items:center;gap:7px;
  font:600 12px var(--mk-font-ui);color:var(--fg-2); }
.pmx{ table-layout:fixed; }
.pmx thead th{ text-align:center; }
.pmx thead th:first-child{ text-align:start;width:38%; }
.pmx .pm-role{ color:var(--fg-2); }
.pm-cat td{ background:var(--bg-2);font:700 11px var(--mk-font-ui)!important;
  letter-spacing:.05em;text-transform:none;color:var(--fg-3)!important;
  padding:8px 16px!important; }
.pm-name{ font:600 13px var(--mk-font-ui);color:var(--fg-1); }
.pm-cell{ text-align:center;cursor:pointer; }
.pmx tbody tr:hover{ background:transparent; }
.pmx tbody tr:not(.pm-cat):hover{ background:var(--bg-2); }
.pm-c{ width:24px;height:24px;border-radius:7px;display:inline-flex;
  align-items:center;justify-content:center; }
.pm-c .mi{ font-size:16px; }
.pm-c.yes{ color:var(--mk-success);background:color-mix(in srgb,var(--mk-success) 14%,transparent); }
.pm-c.part{ color:var(--mk-warning);background:color-mix(in srgb,var(--mk-warning) 16%,transparent); }
.pm-c.no{ color:var(--fg-3);background:color-mix(in srgb,var(--fg-3) 12%,transparent); }

/* ═══ SERVICES · FRONTEND (deployments) ══════════════════════════════ */
.dep-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));gap:14px; }
.dep-card{ background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-lg);padding:16px 18px;
  display:flex;flex-direction:column;gap:12px;cursor:pointer;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast); }
.dep-card:hover{ border-color:var(--fg-3);box-shadow:var(--shadow-sm); }
.dep-h{ display:flex;align-items:center;gap:10px; }
.dep-nm{ font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.dep-h .pill{ margin-inline-start:auto; }
.dep-meta{ display:flex;align-items:center;gap:10px;flex-wrap:wrap; }
.dep-branch{ display:inline-flex;align-items:center;gap:5px;
  font:600 12px var(--mk-font-ui);color:var(--fg-2); }
.dep-branch .mi{ font-size:15px;color:var(--fg-3); }
.dep-commit{ font:600 11px var(--mk-font-mono);color:var(--fg-3);
  background:var(--bg-3);padding:2px 8px;border-radius:6px; }
.dep-foot{ display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding-top:12px;border-top:1px solid var(--divider); }
.dep-by{ display:inline-flex;align-items:center;gap:7px;
  font:600 11px var(--mk-font-ui);color:var(--fg-3); }
.dep-dur{ display:inline-flex;align-items:center;gap:5px;
  font:600 11px var(--mk-font-ui);color:var(--fg-3); }
.dep-dur .mi{ font-size:14px; }
.pill .dot.pulse{ animation:depPulse 1.4s var(--mk-ease) infinite; }
@keyframes depPulse{ 0%,100%{opacity:1} 50%{opacity:.35} }

/* ═══ DETAIL DRAWER (ticket · user · deploy · app) ═══════════════════ */
.dwr-scrim{
  position:fixed;inset:0;background:var(--scrim);
  opacity:0;pointer-events:none;transition:opacity .26s var(--mk-ease);z-index:600;
  -webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px);
}
.dwr-scrim.on{ opacity:1;pointer-events:auto; }
/* B63-118 (Pablo: "the meeting/event panel takes too little space in the width
   of the screen") — 460px was a one-off, narrower than every other detail
   panel in the app (`.filter-panel` etc. all share `--mk-panel-w`, 560px).
   Matching that token instead of a bespoke number is also what keeps it from
   drifting out of sync again. */
.dwr{
  position:fixed;inset-block:0;inset-inline-end:0;width:min(var(--mk-panel-w, 560px),100vw);
  background:var(--bg-1);border-inline-start:1px solid var(--border);
  box-shadow:var(--shadow-lg);z-index:601;display:flex;flex-direction:column;
  transform:translateX(100%);transition:transform .3s cubic-bezier(.4,0,.2,1);
  will-change:transform;
}
[dir=rtl] .dwr{ transform:translateX(-100%); }
.dwr.on,[dir=rtl] .dwr.on{ transform:translateX(0) !important; }
/* B67 R25 (R67-102) — closed, the drawer sat off-screen as an empty unnamed dialog in the accessibility tree; hidden once it has slid out (as R67-034) */
.dwr:not(.on){ visibility:hidden; transition:transform .3s cubic-bezier(.4,0,.2,1), visibility 0s linear .3s; }
.dwr.on{ visibility:visible; transition:transform .3s cubic-bezier(.4,0,.2,1), visibility 0s; }
.dwr-head{
  display:flex;align-items:center;gap:12px;
  padding:16px 18px;border-bottom:1px solid var(--divider);
}
.dwr-head .dwr-eyebrow{ font:600 11px var(--mk-font-mono);color:var(--fg-3);letter-spacing:.02em;
  min-width:0;flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
/* B62 UI-57 — the drawer header's actions are a GROUP, in the same slot and the
   same shape as every other Mocca panel's (`.mp-hd-acts` / `.mp-hd-act`,
   panels.css): one auto-margin on the group instead of one per button, 36px
   circles, 21px glyphs, one hover treatment. B57's rule still holds — Edit sits
   beside Close in the header — it just no longer looks like two loose squares. */
.dwr-head .dwr-hd-acts{ display:flex;align-items:center;gap:4px;margin-inline-start:auto;flex:0 0 auto; }
.dwr-head .dwr-x{
  width:36px;height:36px;border-radius:50%;border:0;cursor:pointer;
  background:transparent;color:var(--fg-2);display:inline-flex;align-items:center;justify-content:center;
  transition:background var(--mk-t-fast),color var(--mk-t-fast);
}
.dwr-head .dwr-x .mi{ font-size:21px; }
.dwr-head .dwr-x:hover{ background:var(--bg-2);color:var(--fg-1); }
.dwr-head .dwr-edit:hover{ background:color-mix(in srgb,var(--accent) 13%,transparent);color:var(--accent-text); }
@media (pointer:coarse){ .dwr-head .dwr-x{ width:40px;height:40px; } }
.dwr-ro{ padding:10px 12px;border-radius:10px;background:var(--bg-2);border:1px dashed var(--border);
  font:600 12.5px var(--mk-font-ui);color:var(--fg-2); }
.dwr-body{ flex:1;min-height:0;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:18px; }
.dwr-foot{ padding:14px 18px;border-top:1px solid var(--divider);display:flex;gap:10px;align-items:center; }
.dwr-foot .btn,.dwr-foot .chip{ flex:0 0 auto; }
.dwr-foot .grow{ flex:1; }

.dwr-title{ font:700 19px var(--mk-font-ui);letter-spacing:-.015em;color:var(--fg-1);
  line-height:1.3;text-wrap:pretty; }
.dwr-meta{ display:grid;grid-template-columns:auto 1fr;gap:10px 16px;align-items:center; }
.dwr-meta .dm-k{ font:600 12px var(--mk-font-ui);color:var(--fg-3); }
.dwr-meta .dm-v{ font:600 13px var(--mk-font-ui);color:var(--fg-1);
  display:inline-flex;align-items:center;gap:7px;justify-self:start; }
.dwr-sec{ display:flex;flex-direction:column;gap:10px; }
.dwr-sec-h{ font:600 11px var(--mk-font-ui);letter-spacing:.05em;text-transform:none;color:var(--fg-3); }
.dwr-p{ font:500 13px var(--mk-font-ui);line-height:1.6;color:var(--fg-2);text-wrap:pretty; }
.dwr-tags{ display:flex;gap:6px;flex-wrap:wrap; }

/* checklist (subtasks / build steps) */
.dwr-check{ display:flex;flex-direction:column;gap:2px; }
.dwr-ci{ display:flex;align-items:center;gap:10px;padding:8px 6px;border-radius:8px;cursor:pointer;
  transition:background var(--mk-t-fast); }
.dwr-ci:hover{ background:var(--bg-2); }
.dwr-ci .box{ width:18px;height:18px;border-radius:6px;border:1.5px solid var(--border);
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;color:transparent;
  transition:background var(--mk-t-fast),border-color var(--mk-t-fast),color var(--mk-t-fast); }
.dwr-ci .box .mi{ font-size:14px; }
.dwr-ci.done .box{ background:var(--accent);border-color:var(--accent);color:#fff; }
.dwr-ci .lab{ font:500 13px var(--mk-font-ui);color:var(--fg-1);flex:1; }
.dwr-ci.done .lab{ color:var(--fg-3);text-decoration:line-through; }
.dwr-ci .dur{ font:600 11px var(--mk-font-mono);color:var(--fg-3); }

/* mini activity feed inside drawer */
.dwr-act{ display:flex;flex-direction:column;gap:14px; }
.dwr-ar{ display:flex;gap:10px;align-items:flex-start; }
.dwr-ar .dwr-at{ font:500 12.5px var(--mk-font-ui);color:var(--fg-2);line-height:1.45; }
.dwr-ar .dwr-at b{ color:var(--fg-1);font-weight:600; }
.dwr-ar .dwr-aw{ font:500 11px var(--mk-font-ui);color:var(--fg-3);margin-top:2px; }
/* B63-116 — attendees group by role (Organizer/Manager/Attendee/Optional/
   Audience); each group reuses `.dwr-act`'s row for its own people. */
.dwr-role-grp{ display:flex;flex-direction:column;gap:10px;margin-top:14px; }
.dwr-role-grp:first-child{ margin-top:10px; }
.dwr-role-h{ font:700 10.5px var(--mk-font-ui);letter-spacing:.05em;text-transform:uppercase;color:var(--fg-3); }
.dwr-join-lists{ display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:12px; }
.dwr-link{ color:var(--accent-text,var(--accent));font:600 12.5px var(--mk-font-ui);text-decoration:none; }
.dwr-link:hover{ text-decoration:underline; }

/* build log (legit mono context) */
.dwr-log{ background:var(--bg-2);border:1px solid var(--border);border-radius:var(--mk-radius-md);
  padding:12px 14px;font:500 11.5px/1.7 var(--mk-font-mono);color:var(--fg-2);
  overflow-x:auto;white-space:pre; }
.dwr-log .ok{ color:var(--mk-success); }
.dwr-log .wn{ color:var(--mk-warning); }
.dwr-bullets{ display:flex;flex-direction:column;gap:8px; }
.dwr-bullet{ display:flex;align-items:flex-start;gap:9px;font:500 13px var(--mk-font-ui);color:var(--fg-2);line-height:1.5; }
.dwr-bullet .mi{ font-size:17px;color:var(--accent-text);flex:0 0 auto;margin-top:1px; }
.dwr-bullet.no{ color:var(--fg-3); }
.dwr-bullet.no .mi{ color:var(--fg-3); }
/* service endpoints */
.dwr-eps{ display:flex;flex-direction:column;gap:6px; }
.dwr-ep{ display:flex;align-items:center;gap:10px;padding:8px 10px;
  background:var(--bg-2);border:1px solid var(--border);border-radius:8px; }
.dwr-ep-m{ font:700 10px var(--mk-font-mono);padding:2px 7px;border-radius:5px;
  color:var(--accent-text);background:color-mix(in srgb,var(--accent) 14%,transparent); }
.dwr-ep-m.post{ color:var(--mk-success);background:color-mix(in srgb,var(--mk-success) 14%,transparent); }
.dwr-ep-p{ flex:1;font:600 12px var(--mk-font-mono);color:var(--fg-1); }
.dwr-ep-l{ font:600 11px var(--mk-font-mono);color:var(--fg-3);font-variant-numeric:tabular-nums; }

/* big header block (user / app) */
.dwr-hero{ display:flex;align-items:center;gap:14px; }
.dwr-hero .dwr-hero-main{ display:flex;flex-direction:column;gap:3px;min-width:0; }
.dwr-hero .dwr-hero-nm{ font:700 18px var(--mk-font-ui);color:var(--fg-1);letter-spacing:-.01em; }
.dwr-hero .dwr-hero-sub{ font:500 13px var(--mk-font-ui);color:var(--fg-3); }
/* form fields (invite / new role / new event) */
.dwr-field{ display:flex;flex-direction:column;gap:7px; }
.dwr-label{ font:600 12px var(--mk-font-ui);color:var(--fg-2); }
.dwr-input,.dwr-textarea{ width:100%;box-sizing:border-box;padding:10px 12px;border-radius:10px;
  background:var(--bg-2);border:1px solid var(--border);color:var(--fg-1);
  font:500 13px var(--mk-font-ui);outline:none;transition:border-color var(--mk-t-fast); }
.dwr-input::placeholder,.dwr-textarea::placeholder{ color:var(--fg-3); }
.dwr-input:focus,.dwr-textarea:focus{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)); }
.dwr-textarea{ resize:vertical;min-height:72px; }
.dwr-row2{ display:grid;grid-template-columns:1fr 1fr;gap:12px; }
.dwr-roles{ display:flex;gap:8px;flex-wrap:wrap; }
.dwr-role-chip{ appearance:none;cursor:pointer;font:600 12px var(--mk-font-ui);
  padding:7px 14px;border-radius:var(--mk-radius-pill);border:1px solid var(--border);
  background:var(--bg-1);color:var(--fg-2);transition:background var(--mk-t-fast),border-color var(--mk-t-fast),color var(--mk-t-fast); }
.dwr-role-chip.on{ background:color-mix(in srgb,var(--accent) 12%,transparent);
  border-color:color-mix(in srgb,var(--accent) 30%,transparent);color:var(--accent-text); }
@media (prefers-reduced-motion:reduce){ .dwr{ transition:none; } }
/* Audit A — the event/meeting/user drawer never had the panel grammar every
   other panel follows (B59 + 064-05: "side panels in desktop, slide-up bottom
   sheets in tablet (top corners a bit rounded) and as a full screen panel in
   mobile (both orientations)"). It stayed a 560px side panel on a tablet and
   on a landscape phone. */
@media (max-width:1024px) and (min-width:601px) and (min-height:600px){
  .dwr{ inset-inline:0;inset-block:auto 0;width:100%;height:min(92dvh, calc(100dvh - 44px));
    border-inline-start:0;border-top:1px solid var(--border);border-radius:20px 20px 0 0;
    box-shadow:0 -18px 48px color-mix(in srgb, var(--scrim, #0d2530) 22%, transparent);
    transform:translateY(102%); }
  [dir=rtl] .dwr{ transform:translateY(102%); }
  .dwr.on,[dir=rtl] .dwr.on{ transform:translateY(0) !important; }
  .dwr > .dwr-head{ position:relative;padding-top:22px; }
  .dwr > .dwr-head::after{ content:'';position:absolute;top:8px;inset-inline-start:50%;transform:translateX(-50%);width:38px;height:4px;border-radius:999px;background:var(--border); }
}
@media (max-width:600px) and (orientation:portrait), (max-height:599px) and (orientation:landscape){
  .dwr{ inset:0;width:100%;height:100%;border-inline-start:0;border-radius:0; }
}

/* ═══ TOASTS ═════════════════════════════════════════════════════════ */
.toast-wrap{
  position:fixed;inset-block-end:24px;inset-inline:0;z-index:680;
  display:flex;flex-direction:column;align-items:center;gap:10px;pointer-events:none;
}
.toast{
  display:inline-flex;align-items:center;gap:10px;
  background:var(--bg-1);border:1px solid var(--border);
  border-radius:var(--mk-radius-pill);box-shadow:var(--shadow-pop);
  padding:11px 18px;font:600 13px var(--mk-font-ui);color:var(--fg-1);
  transform:translateY(10px);opacity:0;pointer-events:auto;
  transition:opacity .22s var(--mk-ease),transform .22s var(--mk-ease);
}
.toast.on{ opacity:1;transform:none; }
.toast .mi{ font-size:18px;color:var(--accent-text); }
.toast.ok .mi{ color:var(--mk-success); }
/* B58 — a refusal (the design-system deploy gate) reads in the danger hue, so a
   blocked deploy does not look like a queued one. */
.toast.bad .mi{ color:var(--mk-danger); }
.toast.bad{ border-color:color-mix(in srgb,var(--mk-danger) 45%,var(--border)); }
@media (prefers-reduced-motion:reduce){ .toast{ transition:opacity .15s; transform:none; } }

/* ═══ CONFIRM DIALOG (Pablo 2026-06-22 — status-change confirmation) ══ */
.cfm-overlay{
  position:fixed;inset:0;z-index:720;display:flex;align-items:center;justify-content:center;
  background:color-mix(in srgb, var(--mk-scrim, #0b1620) 46%, transparent);
  backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  opacity:0;transition:opacity .18s var(--mk-ease);padding:24px;
}
.cfm-overlay.on{ opacity:1; }
.cfm-card{
  background:var(--bg-1);border:1px solid var(--border);border-radius:var(--mk-radius-lg);
  box-shadow:var(--shadow-pop);width:min(380px,100%);padding:20px 22px;
  transform:translateY(8px) scale(.98);transition:transform .18s var(--mk-ease);
}
.cfm-overlay.on .cfm-card{ transform:none; }
.cfm-h{ display:flex;align-items:center;gap:10px;font:700 16px var(--mk-font-ui);color:var(--fg-1); }
.cfm-h .mi{ font-size:22px;color:var(--accent-text); }
.cfm-b{ margin-top:10px;font:500 13.5px/1.55 var(--mk-font-ui);color:var(--fg-2); }
.cfm-ft{ margin-top:20px;display:flex;justify-content:flex-end;gap:10px; }
@media (prefers-reduced-motion:reduce){ .cfm-overlay,.cfm-card{ transition:opacity .12s; transform:none; } }

/* ── RESPONSIVE ──────────────────────────────────────────────────── */
@media (max-width:1000px){
  /* Single-pane: list fills the surface; the thread slides in from the
     inline-end over a scrim, with a back button to return to the list.
     VC-R1 — clip the container so the off-screen (translateX(100%)) thread
     pane never inflates the page scroll width on tablet/mobile. */
  .chat{ display:flex;flex-direction:column;overflow:hidden; }
  .chat-thread{
    position:absolute;inset-block:0;inset-inline-end:0;
    width:100%;
    transform:translateX(100%);visibility:hidden;
    box-shadow:var(--shadow-lg);z-index:30;
    transition:transform var(--mk-t-base) var(--mk-ease),visibility 0s linear var(--mk-t-base);
  }
  html[dir="rtl"] .chat-thread{ transform:translateX(-100%); }
  .chat.show-thread .chat-thread{ transform:none;visibility:visible;transition:transform var(--mk-t-base) var(--mk-ease); }
  .chat-scrim{
    display:block;position:absolute;inset:0;z-index:20;
    background:rgba(0,0,0,.30);opacity:0;pointer-events:none;
    transition:opacity var(--mk-t-base) var(--mk-ease);
  }
  .chat.show-thread .chat-scrim{ opacity:1;pointer-events:auto; }
  .ct-back{ display:inline-flex; }
  /* Tablet↓: list is fully flush — no card chrome, no page gutter around the
     messages list (Pablo 2026-06-21: "we shouldn't even see padding around
     the messages list in tablet view"). */
  .page-view[data-view="chat"] .page > .chat{ padding:0; }
  .chat-list{ border:0;border-radius:0; }
  /* Full-screen slide-in thread on tablet↓ — flush, no card rounding/border
     (Pablo 2026-06-21: "rounded corners within the messages screen, why?"). */
  .chat-thread{ border:0;border-radius:0; }
  .chat-list-h{ padding-inline:16px; }
  .chat-convs{ padding:0; }
  .chat-conv{ border-radius:0;padding-inline:16px; }
  .chat-search{ margin:8px 16px; }
  /* Fullscreen conversation (Pablo 2026-06-21): when a thread is open, the
     navbar, the bottom tab bar AND the page FAB all hide so the conversation
     owns the whole screen (portrait + landscape). The thread already covers
     the body as an absolute slide-in; collapsing the page's nav offset lets
     it start at the very top. */
  /* Fullscreen conversation hide (nav/tab-bar/FAB) is MOBILE-ONLY now — it
     lived here under max-width:1000px, which also caught TABLET and killed the
     tablet navbar (Pablo 2026-06-22: "not seeing the navbar in tablet view
     (Chat)"). Moved to the mobile-portrait + mobile-landscape blocks below.
     On tablet the thread still slides in over the list pane, chrome intact. */
  /* The "Add transaction" FAB is dashboard-only — it must never appear on
     Chat (Pablo: "what is this button in Chat???"). Hide it on the chat page. */
  .shell.signed-in:has(.body-in[data-page="chat"]) .page-fab{ display:none; }
  .map-wrap{ grid-template-columns:1fr; }
}
/* Fullscreen chat thread must fill the WHOLE viewport (Pablo 2026-06-22:
   "blank space left on the conversation view in mobile — should take full
   height"). Hiding .nav / .tb leaves their reserved grid tracks empty, so a
   nav-height band at the top and a tabbar-height band at the bottom read as
   blank space. Collapse those tracks to 0 while a thread is open so the chat
   page owns the full screen. Scoped per layout: mobile-V + tablet collapse
   the top/bottom ROWS; mobile-H landscape collapses the left rail COLUMN. */
@media (max-width:600px) and (orientation:portrait){
  /* mobile-V signed-in is a 2-ROW grid (1fr / tabbar). Collapse the tabbar row
     ONLY — the old `0 minmax(0,1fr) 0` declared a phantom 3rd row and put the
     BODY (grid-row:1/2) on a 0-height track, blanking the conversation view
     (Pablo 2026-06-22: "opened a conversation in mobile portrait — blank
     screen"). */
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread){ grid-template-rows:minmax(0,1fr) 0 !important; }
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .nav,
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .tb,
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .page-fab{ display:none !important; }
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .page-view[data-view="chat"] .page{ padding-top:0; }
  /* Audit S10 · B63-007 re-check ("a chat window doesn't take full screen. I'm
     seeing a whitespace above the header of the chat") — the page's first child
     carries the floating navbar's clearance (`--mk-nav-clear`, 60px); with the
     navbar hidden in an open thread that clearance was the whitespace. */
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .page-view[data-view="chat"] .page > :first-child{ margin-top:0 !important; }
}
@media (max-height:599px) and (orientation:landscape){
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread){ grid-template-columns:0 minmax(0,1fr) !important; }
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .nav,
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .tb,
  .shell.signed-in:has(.body[data-page="chat"] .chat.show-thread) .page-fab{ display:none !important; }
}
/* Audit S5 · B63-132 ("sometimes when I've clicked through a lot of flows, the
   navbar disappears and I have to refresh") — every rule above keyed on
   `:has(.chat.show-thread)`, but the Chat page keeps that class after you
   navigate away with a conversation open, so the navbar (and the tab bar, the
   FAB, the grid rows) stayed hidden on every other route. They now read the
   thread as open only while Chat IS the current page. */
/* SH-01/SH-07 (2026-07-02): 680 → 600 — these are MOBILE treatments and must
   not leak into the 601–720 tablet band (B18 moved the boundary to 600/601). */
@media (max-width:600px){
  .feed-row{ grid-template-columns:64px 1fr;gap:10px; }
  .tbl .hide-sm{ display:none; }
  .ag-row{ grid-template-columns:60px 1fr;gap:10px; }
  .wk-head,.wk-grid{ grid-template-columns:44px repeat(7, 18vw); }
  .page-view.wk-weekdays .wk-head,
  .page-view.wk-weekdays .wk-grid{ grid-template-columns:44px repeat(5, 18vw); }
  .mo-cell{ min-height:74px;padding:5px; }
  .mo-ev{ font-size:9px;padding:1px 4px;gap:3px; }
  /* at this width the hour and the bubbles would leave no room for the title */
  .mo-ev-ppl{ display:none; }
}
/* Mobile-PORTRAIT: squish the Week grid tighter and narrow the Gantt lane
   column so more of the chart/week is visible on a phone (Pablo 2026-06-22). */
@media (max-width:600px) and (orientation:portrait){
  .wk-head,.wk-grid{ grid-template-columns:36px repeat(7, 13vw); }
  .page-view.wk-weekdays .wk-head,
  .page-view.wk-weekdays .wk-grid{ grid-template-columns:36px repeat(5, 13vw); }
  .wk-day{ padding:7px 2px; }
  .wk-corner{ min-width:0; }
  .gantt-wrap{ --gantt-lane-w:138px; }
  .gantt-lane{ padding:8px 10px;gap:7px; }
  .gantt-type{ font-size:15px; }
}
/* ── KANBAN responsive (Pablo 2026-06-22) ──────────────────────────────
   Mobile-PORTRAIT and TABLET stack the columns vertically into one column
   and let the PAGE scroll down through Backlog → In Progress → … (the old
   4×80vw horizontal scroll was "completely broken" on a phone). Mobile-
   LANDSCAPE and DESKTOP keep the horizontal multi-column board. */
@media (max-width:600px) and (orientation:portrait),
       (min-width:601px) and (max-width:1024px) and (min-height:600px){
  .kanban{
    grid-template-columns:1fr;
    grid-auto-rows:max-content;
    overflow-x:visible;
    flex:0 0 auto;          /* grow with content; the page is the scroll surface */
    min-height:0;
    gap:12px;
  }
  /* A stacked column shouldn't try to fill leftover height — size to its
     cards so the next column starts right below. */
  .kanban .kb-col{ min-height:0; }
}
/* Sec-view sticky headers sit over light cards (no dark balance banner
   under them like the dashboard), so the pure backdrop-blur glass let too
   much scrolled content show through — it read as "much clearer than
   dashboard" (Pablo 2026-06-19). Give the header glass a frosted bg-1 fill
   so scrolled content is obscured into a solid surface, matching the
   dashboard. At rest the fill matches the body canvas, so no visible band. */
/* Reuse the Dashboard header treatment verbatim on section views (Services
   backend/frontend, etc.) — Pablo 2026-06-21: "re-use that header… it doesn't
   have a solid background color, has blur and opacity where content scrolls
   behind it." So at REST the header is transparent (no band); only once
   content scrolls under it does a light frosted fill + the inherited
   backdrop-blur kick in, obscuring the content without going fully solid.
   (Was an always-on 86% bg-1 fill, which read as a solid dark bar.) */
/* Reuse the Dashboard header treatment verbatim on section views (Services
   backend/frontend, etc.). Pablo B11-07: the Frontend Components panel scrolls
   INTERNALLY, so `.page` scrollTop never moves → `body.scrolled` never sets →
   the header stayed fully transparent ("still very see through"). Give sec-view
   headers a persistent frosted fill at rest so they read as a glass band (like
   the dashboard header does over content), and deepen it once content scrolls
   behind. Blur (inherited from .page-h::before) keeps it glassy, not a solid bar. */
/* Sec-view headers behave EXACTLY like the dashboard header: no own fill, so
   the header background IS the content backdrop showing through (identical by
   construction — Pablo 2026-06-24: "the header shouldn't have a different
   background color than the main content"). The inherited backdrop-blur on
   .page-h::before still glasses anything that scrolls underneath. (Earlier I
   gave it an opaque bg-1 fill for B11-07's "not see-through" — but bg-1 is a
   different shade than the content surface, which is exactly the mismatch he
   flagged. Matching the dashboard = transparent at rest.) */

/* Mobile keeps the section header's segmented view-switcher visible.
   The shell hides ALL header actions on mobile (they fold into the FAB),
   but a sec-view's .seg is NAVIGATION (Today/Week/Month, Board/Timeline) —
   every desktop action must stay reachable on mobile too (Pablo 2026-06-19).
   Higher specificity (.shell.signed-in.sec-view.page-h.acts) beats the
   shell's display:none, so it holds in both mobile-V and mobile-H. */
.shell.signed-in .sec-view .page-h .acts{ display:flex; }

@media (max-width:560px){
  .sec-view .page-h .acts,
  .sec-view .page-h > div:last-child{ width:100%; }
  .sec-view .page-h .acts{ flex-wrap:wrap; }
  /* Segmented controls + new-buttons stretch a bit for touch */
  .sec-view .page-h .seg{ flex:1; }
  .sec-view .page-h .seg button{ flex:1;justify-content:center; }
  /* Toolbars: search takes the row, chips wrap under */
  .sec-view .sec-toolbar{ gap:8px; }
  .sec-view .sec-search{ min-width:0;flex:1 1 100%;order:-1; }
  /* KPIs: two-up instead of one-wide-row */
  .sec-view .kpi-row{ gap:8px; }
  .sec-view .kpi{ flex:1 1 calc(50% - 4px);padding:12px 14px; }
  .sec-view .kpi .kpi-v{ font-size:20px; }
  /* Permissions matrix: tighten so 5 columns fit a phone */
  .pmx thead th:first-child{ width:44%; }
  .pmx thead th,.pmx tbody td{ padding:9px 8px; }
  .pm-name{ font-size:12px; }
  .pmx .pm-role{ font-size:10px; }
  .pm-c{ width:22px;height:22px; }
  /* Drawer meta: let long values wrap rather than clip */
  .dwr-meta{ grid-template-columns:1fr; gap:4px 0; }
  .dwr-meta .dm-v{ margin-bottom:8px; }
  .map-mount{ min-height:300px; }
}

/* ═══ TICKETS · GANTT ════════════════════════════════════════════════ */
.gantt-wrap{ flex:1;min-height:0;overflow:auto; --gantt-lane-w:240px; }
.gantt{ min-width:680px; }
/* B63-112 (Pablo: "Let's have more options on the timeline view because I want to
   see the scenarios where there would need to be some scroll") — every existing
   range (Week/Month/Quarter/Year) lays its ticks out as pure proportional flex, so
   the chart always fits `.gantt-wrap` and the scroll it already supports never
   actually triggers. `.gantt-tight` (the new "2 Weeks" zoom) floors each day's
   track to a real minimum width instead, so a real 14-day span can genuinely
   outgrow the viewport. */
.gantt.gantt-tight .gantt-head .gantt-track,
.gantt.gantt-tight .gantt-body .gantt-track{ min-width:calc(var(--gantt-days, 14) * 46px); }
.gantt-head{ display:flex;align-items:stretch;position:sticky;top:0;z-index:3;
  background:var(--bg-1);border-bottom:1px solid var(--border); }
.gantt-lane{ flex:0 0 var(--gantt-lane-w);width:var(--gantt-lane-w);
  display:flex;align-items:center;gap:10px;
  padding:8px 14px;border-inline-end:1px solid var(--divider);min-width:0; }
.gantt-lane-main{ display:flex;flex-direction:column;gap:1px;min-width:0; }
.gantt-type{ flex:0 0 auto;font-size:18px;color:var(--fg-2); }
.gantt-corner{ background:var(--bg-2); }
.gantt-track{ position:relative;flex:1;min-width:0;display:flex; }
.gantt-head .gantt-track{ background:var(--bg-2); }
.gantt-hcell{ flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1px;padding:8px 4px;border-inline-start:1px solid var(--divider);min-width:0; }
.gantt-hcell.wknd{ background:color-mix(in srgb,var(--fg-3) 7%,transparent); }
.gantt-hcell.today{ background:color-mix(in srgb,var(--accent) 12%,transparent); }
.gantt-hcell .gh-dow{ font:600 10px var(--mk-font-ui);color:var(--fg-3);text-transform:none; }
.gantt-hcell .gh-date{ font:700 13px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center; }
.gantt-hcell.today .gh-date{ color:var(--accent-text); }
.gantt-body{ position:relative; }
/* B57 — BLOCKER LINKS. The svg sits under the bars (they are z-index:2) so every
   bar control stays clickable; only the invisible hit stroke takes the pointer,
   which is what carries the link's tooltip. A red link is a schedule that cannot
   hold: the blocked bar starts before its blocker ends. */
.gantt-links{ position:absolute;top:0;left:0;pointer-events:none;z-index:1;overflow:visible; }
/* B63-108 (Pablo: "it should only cover the child items of the expanded project.
   The other projects and tickets would still show up in other columns but this box
   shouldn't be on top of those columns") — superseding B59's full-width banner: the
   row mirrors the axis+plot layout below it (same 56px spacer) so the track's 0–100%
   lines up with the SAME lanei/w math the cards use, and the button is absolutely
   positioned inside that track at exactly the focused project's column range —
   never wider than its own children, never over unrelated columns. */
.gantt-vfocus-row{ display:flex;align-items:stretch;margin:0 0 10px; }
.gantt-vfocus-spacer{ flex:0 0 56px;width:56px; }
.gantt-vfocus-track{ position:relative;flex:1;min-width:0;min-height:38px; }
.gantt-vfocus{ position:absolute;top:0;display:flex;align-items:center;gap:8px;margin:0;padding:8px 12px;
  border:1px solid color-mix(in srgb,var(--accent) 32%,var(--border));border-radius:var(--mk-radius-lg);
  background:color-mix(in srgb,var(--accent) 7%,transparent);cursor:pointer;text-align:start;
  font:600 12px/1.35 var(--mk-font-ui);color:var(--fg-1); }
.gantt-vfocus:hover{ background:color-mix(in srgb,var(--accent) 12%,transparent); }
.gantt-vfocus > .mi{ font-size:17px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.gantt-vfocus > span:nth-child(2){ flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.gantt-vfocus-x{ flex:0 0 auto;display:inline-flex;align-items:center;gap:3px;padding:3px 9px 3px 6px;
  border-radius:var(--mk-radius-pill);background:var(--bg-1,#fff);box-shadow:inset 0 0 0 1px var(--border);
  font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.gantt-vfocus-x .mi{ font-size:13px; }
.gantt-vfocus:hover .gantt-vfocus-x{ color:var(--accent-text,var(--accent));box-shadow:inset 0 0 0 1px var(--accent); }
/* ── B59 — the connectors, per Pablo's four asks on one line ──────────────
   "I don't like the question mark pointer when hovering on these lines. Also please
   make them a bit thicker use rounded curves on the turn of the arrows, use a more
   nicely looking arrowhead and (I'm not sure how to do this) but maybe a visual
   element when a line is crossing over a bar so that the user can tell it's just
   passing through."
   • the pointer: `help` announced an explanation that never arrives (the tooltip is
     the same one every bar has), so it is the plain pointer now — the line IS
     hoverable, and hovering lights its whole dependency chain.
   • B63-111 (Pablo: "slightly curvier and more subtle … shouldn't steal attention"):
     thin + a touch translucent at rest (1.6/.82), a wider corner radius (13, in
     sections.js's `roundPoly`) so turns read as a soft curve, full weight/opacity
     only on hover/hot.
   • rounded turns + the new arrowhead are geometry, in sections.js.
   • crossing a bar: `.gl-case` (the halo) + `.gl-xing` (the bridge). */
.gl-line{ fill:none;stroke:color-mix(in srgb,var(--accent) 44%,var(--fg-3));stroke-width:1.6;opacity:.82;
  stroke-linejoin:round;stroke-linecap:round;transition:stroke-width var(--mk-t-fast),stroke var(--mk-t-fast),opacity var(--mk-t-fast); }
.gl-case{ fill:none;stroke:var(--bg-1,#fff);stroke-width:6;stroke-linejoin:round;stroke-linecap:round;opacity:.92; }
.gl-ar{ fill:color-mix(in srgb,var(--accent) 58%,var(--fg-3));stroke:var(--bg-1,#fff);stroke-width:1.2;
  paint-order:stroke;transition:fill var(--mk-t-fast); }
/* the bridge sits ON the bar the line runs over, in the surface colour, outlined in
   the line's own colour — so the line visibly hops rather than terminating there. */
.gl-xing{ fill:var(--bg-1,#fff);stroke:color-mix(in srgb,var(--accent) 58%,var(--fg-3));stroke-width:1.1;opacity:.95; }
.gl.is-hot .gl-xing{ stroke:var(--accent);opacity:1; }
.gl-bad .gl-xing{ stroke:var(--mk-danger); }
.gl-hit{ fill:none;stroke:transparent;stroke-width:14;pointer-events:stroke;cursor:pointer; }
.gl-bad .gl-line{ stroke:var(--mk-danger);stroke-dasharray:5 3; }
.gl-bad .gl-ar{ fill:var(--mk-danger); }
.gl.is-hot .gl-line,.gl:hover .gl-line{ stroke-width:2.6;opacity:1; }
.gl.is-hot .gl-case,.gl:hover .gl-case{ stroke-width:7.5; }
.gl.is-hot .gl-ar,.gl:hover .gl-ar{ fill:var(--accent); }
.gl.is-hot.gl-bad .gl-ar,.gl:hover.gl-bad .gl-ar{ fill:var(--mk-danger); }
.gl.is-hot .gl-line{ stroke:var(--accent); }
.gl.is-hot.gl-bad .gl-line{ stroke:var(--mk-danger); }
/* the dots mark WHICH edges the dependency ties together — only worth showing
   while the link is the thing you are looking at. */
.gl-dot{ fill:var(--accent);opacity:0;transition:opacity var(--mk-t-fast); }
.gl-bad .gl-dot{ fill:var(--mk-danger); }
.gl.is-hot .gl-dot,.gl:hover .gl-dot{ opacity:1; }
/* ── B57 (Pablo) — PROJECT ROWS + the rolled-up bar ─────────────────────────
   A project row is a container, not a ticket: its column carries the disclosure
   and the child count, and its bar is not draggable (no dates of its own). The
   idle stretches — the days inside the span where no child is scheduled — are
   diagonal barbershop bands, so the bar cannot pretend to be solid work. */
.gantt-row-proj{ background:color-mix(in srgb,var(--accent) 4%,var(--bg-1)); }
.gantt-row-proj:hover{ background:color-mix(in srgb,var(--accent) 7%,var(--bg-2)); }
.gantt-lane-proj{ gap:4px;padding-inline-start:4px; }
.gantt-lane-proj .gantt-tt{ font-weight:700; }
html[dir="rtl"] .gantt-tt{ unicode-bidi:plaintext; text-align:right; }   /* B67 R67-075 — Latin lane titles cut at their start in Arabic (R67-014) */
.gantt-lane-proj .gantt-type{ color:var(--accent); }
.gantt-proj-tw{ flex:0 0 auto;display:grid;place-items:center;width:22px;height:22px;
  border:0;background:transparent;color:var(--fg-2);border-radius:var(--mk-radius-sm);cursor:pointer; }
.gantt-proj-tw:hover{ background:color-mix(in srgb,var(--fg-3) 14%,transparent);color:var(--fg-1); }
/* B62 UI-61 — the project's own create button, borrowing the backend tree's `+`
   grammar (`.nt-act[data-nt-add]`): quiet until the row is hovered, and ALWAYS
   visible under a coarse pointer, where there is no hover to reveal it with.
   B62 UI-65 — the whole project row / card is the disclosure, so it says so with a
   pointer cursor, and both controls grow to a 34px target on touch (the precedent
   is this file's own `.map-layer-seg button{min-height:38px}`). */
.gantt-proj-add{ flex:0 0 auto;display:grid;place-items:center;width:22px;height:22px;
  border:0;background:transparent;color:var(--fg-3);border-radius:var(--mk-radius-sm);cursor:pointer;
  opacity:0;transition:opacity var(--mk-t-fast),background var(--mk-t-fast),color var(--mk-t-fast); }
.gantt-proj-add .mi{ font-size:17px; }
.gantt-row-proj:hover .gantt-proj-add,.gantt-proj-add:focus-visible{ opacity:1; }
.gantt-proj-add:hover{ background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent-text); }
.gantt-lane-proj{ cursor:pointer; }
.gantt-vcard-ft .gantt-proj-add{ opacity:1;margin-inline-start:auto; }
.gantt-vcard.gantt-vcard-proj .gantt-proj-add{ color:#fff; }
.gantt-vcard.gantt-vcard-proj .gantt-proj-add:hover{ background:rgba(255,255,255,.22);color:#fff; }
@media (pointer:coarse){
  .gantt-proj-add{ opacity:1;width:34px;height:34px; }
  .gantt-proj-add .mi{ font-size:20px; }
  .gantt-proj-tw{ width:34px;height:34px; }
  .gantt-proj-tw .mi{ font-size:22px; }
}
.gantt-proj-tw .mi{ font-size:18px;transition:transform var(--mk-t-fast); }
.gantt-row-proj.is-open .gantt-proj-tw .mi,.gantt-vcard-proj.is-open .gantt-proj-tw .mi{ transform:rotate(90deg); }
:root[dir="rtl"] .gantt-proj-tw .mi{ transform:rotate(180deg); }
:root[dir="rtl"] .gantt-row-proj.is-open .gantt-proj-tw .mi{ transform:rotate(90deg); }
/* B59 (Pablo: "I don't like this bubble. I like the idea of showing the count of
   child tickets but not with these styles") — the accent-filled pill was the loudest
   thing in a lane whose actual subject is the project's title, and it read as a
   notification badge (an alert), not as a count. It is a MARK now: the ticket glyph
   the rest of the app uses for a ticket, plus the number, in the lane's own quiet
   meta tone — the same treatment as `.gantt-type`, so it sits in the row instead of
   shouting over it. */
.gantt-proj-n{ flex:0 0 auto;display:inline-flex;align-items:center;gap:3px;padding:0;
  background:none;color:var(--fg-3);font:700 11px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.gantt-proj-n .mi{ font-size:14px;color:var(--fg-3);opacity:.75; }
.gantt-lane-proj:hover .gantt-proj-n,.gantt-lane-proj:hover .gantt-proj-n .mi{ color:var(--fg-2); }
.gantt-bar.gantt-bar-roll{ cursor:default;background:color-mix(in srgb,var(--accent) 82%,var(--fg-1));
  height:20px;padding:0 6px; }
.gantt-roll-fill{ position:absolute;inset-inline-start:0;top:0;bottom:0;
  background:rgba(255,255,255,.22);pointer-events:none; }
.gantt-roll-idle{ position:absolute;top:0;bottom:0;pointer-events:auto;
  background:repeating-linear-gradient(45deg,
    color-mix(in srgb,var(--bg-1) 88%,transparent) 0 4px,
    color-mix(in srgb,var(--fg-3) 40%,transparent) 4px 8px); }
.gantt-roll-idle.v{ inset-inline:0;top:auto;bottom:auto; }
.gantt-row-child .gantt-lane{ padding-inline-start:30px; }
.gantt-row-child{ background:color-mix(in srgb,var(--accent) 2%,transparent); }
/* B62 UI-65 — THE ROOT CAUSE of "I can't find a way to expand this project on
   vertical view": this card was never painted. `.gantt-vcard-proj{background:…}`
   (0,1,0) sits ABOVE `.gantt-vcard{background:var(--bg-1)}` in this file, so the
   base rule won on source order and the project card rendered WHITE — with white
   ink on it. The chevron, the ticket count and the new + were all invisible, and
   the title was the only thing you could see. Doubling the class (0,2,0) makes the
   accent field win regardless of where either rule lives.
   The field is also DEEPER than B57's `accent 82% / --fg-1`, for two reasons
   measured on screen: white ink on that mix is 3.43:1 (a 12px title needs 4.5),
   and mixing toward `--fg-1` FLIPS with the theme — fg-1 is near-white in dark, so
   the "darkened" field became a pale one and the white ink got worse. Mixing
   toward a fixed deep ground instead gives ONE value that is identical in both
   themes: white ink measures 4.9:1 on it (70% measured 4.29 — just under — so the
   ground carries more weight than the arithmetic predicted; the number below is
   the measured one, not a computed guess), and on the dark canvas the card is
   still the lighter object. */
.gantt-vcard.gantt-vcard-proj{ background:color-mix(in srgb,var(--accent) 60%,#0A1A22);border-color:transparent; }
.gantt-vcard.gantt-vcard-proj .gantt-vcard-tt,
.gantt-vcard.gantt-vcard-proj .gantt-vcard-id{ color:#fff; }
.gantt-vcard.gantt-vcard-proj .gantt-proj-tw{ color:rgba(255,255,255,.92); }
.gantt-vcard.gantt-vcard-proj .gantt-proj-tw:hover{ background:rgba(255,255,255,.18);color:#fff; }
.gantt-vcard.gantt-vcard-proj .gantt-proj-n,
.gantt-vcard.gantt-vcard-proj .gantt-proj-n .mi,
.gantt-vcard.gantt-vcard-proj .gantt-vcard-ft .gantt-type{ background:none;color:rgba(255,255,255,.94); }
/* B57 - the project chip: the same fact on the board card, the backlog row and
   the ticket panel. Only the panel's is a control (it goes to the chart). */
.tk-proj-chip{ display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;
  height:20px;padding:0 7px;border:0;border-radius:var(--mk-radius-pill);
  background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent);
  font:700 10px var(--mk-font-mono);letter-spacing:.02em;max-width:100%; }
.tk-proj-chip .mi{ font-size:13px; }
.tk-proj-chip .tk-proj-id{ overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.tk-proj-chip.is-go{ cursor:pointer;transition:background var(--mk-t-fast); }
.tk-proj-chip.is-go:hover{ background:color-mix(in srgb,var(--accent) 20%,transparent); }
.tk-proj-chip .tk-proj-go{ font-size:14px;opacity:.7; }
.tbl .tk-proj-chip{ margin-inline-start:8px;vertical-align:middle; }
/* B60 - the EMPTY state of the same chip: a ticket with no parent still carries a
   slot, dashed and quiet, and clicking it opens the project menu. It must read as
   an invitation, not as a project called "Project" - hence the outline instead of
   the accent fill, and the + glyph. */
.tk-proj-chip.is-add{ cursor:pointer;background:transparent;color:var(--fg-3);
  border:1px dashed var(--border-strong,var(--border));font-family:var(--mk-font-ui);
  font-weight:700;font-size:10px;transition:color var(--mk-t-fast),border-color var(--mk-t-fast),background var(--mk-t-fast); }
.tk-proj-chip.is-add:hover{ color:var(--accent-text,var(--accent));border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 8%,transparent); }
.tk-proj-chip.is-add .mi{ font-size:12px; }
@media (pointer:coarse){ .tk-proj-chip.is-add{ height:24px; } }
/* arriving from a ticket - say which row answered the question */
.gantt-row-proj.is-landed,.gantt-vcard-proj.is-landed{ animation:tkProjLand 1.4s ease-out; }
@keyframes tkProjLand{ 0%,40%{ background:color-mix(in srgb,var(--accent) 22%,var(--bg-1)); } 100%{ background:color-mix(in srgb,var(--accent) 4%,var(--bg-1)); } }
.gantt-row{ display:flex;align-items:stretch;border-bottom:1px solid var(--divider);
  cursor:pointer;transition:background var(--mk-t-fast);min-height:48px; }
/* B54 — a bar dragged VERTICALLY re-orders the lanes; the row it belongs to
   lifts while it travels so the swap is legible. */
.gantt-row-reordering{ background:color-mix(in srgb,var(--accent) 7%,var(--bg-2));
  box-shadow:0 10px 22px -14px rgba(13,37,48,.4);position:relative;z-index:2; }
.gantt-row:hover{ background:var(--bg-2); }
.gantt-row .gantt-id{ font:600 11px var(--mk-font-mono);color:var(--fg-3); }
.gantt-row .gantt-tt{ font:600 13px var(--mk-font-ui);color:var(--fg-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.gantt-grid{ position:absolute;inset:0;display:flex;pointer-events:none; }
.gantt-grid span{ flex:1;border-inline-start:1px solid var(--divider); }
.gantt-grid span.wknd{ background:color-mix(in srgb,var(--fg-3) 5%,transparent); }
.gantt-grid span.today{ background:color-mix(in srgb,var(--accent) 8%,transparent); }
.gantt-bar{ position:absolute;top:50%;transform:translateY(-50%);height:26px;
  border-radius:var(--mk-radius-pill);display:flex;align-items:center;gap:6px;
  padding:0 8px 0 10px;overflow:hidden;z-index:2;cursor:grab;touch-action:none;
  /* B50-03 (Pablo: "there's a minimum width to this") — a short ticket at a
     coarse truncation used to collapse and drop its avatar + priority box. The
     pill is now floored at the width those two need, so they always fit. */
  min-width:var(--gantt-bar-min,66px);
  background:var(--accent);box-shadow:var(--shadow-sm); }
.gantt-bar.gantt-bar-dragging{ cursor:grabbing;box-shadow:var(--shadow-md);z-index:5;opacity:.92; }
/* Right-edge resize handle — drag to extend/shrink the due date. */
.gantt-bar-resize{ position:absolute;inset-inline-end:0;top:0;bottom:0;width:10px;
  cursor:ew-resize;border-radius:0 var(--mk-radius-pill) var(--mk-radius-pill) 0;
  background:linear-gradient(to right, transparent, rgba(255,255,255,.28));
  opacity:0;transition:opacity var(--mk-t-fast);touch-action:none; }
.gantt-bar:hover .gantt-bar-resize{ opacity:1; }
.gantt-bar .gantt-bar-prio{ font-size:16px;color:#fff;flex:0 0 auto; }
.gantt-bar .gantt-bar-l{ font:600 11px var(--mk-font-ui);color:#fff;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis; }
.gantt-bar .av{ flex:0 0 auto;width:20px;height:20px;font-size:8px;
  border:1.5px solid rgba(255,255,255,.7); }
/* B44 C9 (Pablo) — priority in a small distinct box. B50-04 (Pablo: "Why are
   these outside of the bar? I want them inside") — it now rides INSIDE the pill
   next to the avatar; `.in-bar` neutralises the old absolute positioning.
   B51-25 (Pablo 2026-08-19: "These priority items are not looking well…") — the
   in-bar chip was an OPAQUE WHITE 18px square with a white-ish border and a
   coloured glyph: a sticker patched onto a saturated pill, and 19px of content
   in a 16px content box (it reported scrollWidth > clientWidth). It is now a
   round translucent wash in the bar's own light, with the glyph in white — the
   same grammar as the in-bar avatar ring — and priority reads from the wash
   (danger fill for High) instead of from a border colour nobody can see. */
.gantt-bar-prio-box{ position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  display:grid;place-items:center;width:19px;height:19px;border-radius:6px;
  background:var(--bg-1);border:1px solid var(--divider);box-shadow:var(--shadow-sm);color:var(--fg-3); }
.gantt-bar-prio-box.in-bar{ position:static;transform:none;flex:0 0 auto;
  width:20px;height:20px;border-radius:999px;background:rgba(255,255,255,.22);
  border:0;box-shadow:none;color:#fff;padding:0;overflow:hidden; }
.gantt-bar-prio-box.in-bar .mi{ font-size:14px; }
.gantt-bar-prio-box.in-bar.prio-hi{ background:color-mix(in srgb,var(--mk-danger) 88%,transparent);color:#fff; }
.gantt-bar-prio-box.in-bar.prio-md{ background:rgba(255,255,255,.24);color:#fff; }
.gantt-bar-prio-box.in-bar.prio-lo{ background:rgba(255,255,255,.14);color:rgba(255,255,255,.86); }
.gantt-bar-prio-box .mi{ font-size:14px;line-height:1; }
.gantt-bar-prio-box.prio-hi{ color:var(--mk-danger);border-color:color-mix(in srgb,var(--mk-danger) 45%,var(--divider)); }
.gantt-bar-prio-box.prio-md{ color:var(--accent-text);border-color:color-mix(in srgb,var(--accent) 45%,var(--divider)); }
.gantt-bar-prio-box.prio-lo{ color:var(--fg-3); }
/* B50-03 — the old "tiny bar" treatment (hide the contents below ~7% width) is
   replaced by the min-width floor above; the class is kept only so an existing
   markup path can't break, and no longer hides anything. */
.gantt-bar-tiny{ padding:0 8px 0 10px;gap:6px; }

/* ── B50-02 — OPEN-ENDED bars: a start with "no end in sight" ──────────────
   Pablo: "not rounding the right side border and adding a disappearing gradient
   at the end so that it's understood that the task has no end in sight, obviously
   ending at the screen's right margin." The bar runs to the window's right edge,
   loses its trailing radius and fades out with a mask. */
.gantt-bar-open{ border-start-end-radius:0;border-end-end-radius:0;cursor:copy;
  -webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 96px),transparent 100%);
  mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 96px),transparent 100%); }
[dir="rtl"] .gantt-bar-open{
  -webkit-mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 96px),transparent 100%);
  mask-image:linear-gradient(to left,#000 0,#000 calc(100% - 96px),transparent 100%); }
/* A range that starts before the window also loses its LEADING radius, so the
   clipped edge never reads as a real start. */
.gantt-bar-clipstart{ border-start-start-radius:0;border-end-start-radius:0; }

/* ── B50-01 / B50-02 — phantom bar + date tag ─────────────────────────────── */
.gantt-track-live{ cursor:copy; }
.gantt-row-nodue .gantt-track-live .gantt-nodue-chip{ opacity:.35; }
.gantt-bar-phantom{ pointer-events:none;z-index:4;cursor:copy;
  background:color-mix(in srgb,var(--accent) 22%,transparent);
  border:1.5px dashed color-mix(in srgb,var(--accent) 70%,transparent);
  box-shadow:none;color:var(--accent-text,var(--accent));
  justify-content:center;padding:0 6px; }
.gantt-bar-phantom .mi{ font-size:15px; }
.gantt-phantom-tag{ position:fixed;z-index:2400;pointer-events:none;
  padding:4px 9px;border-radius:8px;white-space:nowrap;
  background:var(--fg-1);color:var(--bg-1);
  font:700 11px/1.2 var(--mk-font-ui);box-shadow:var(--shadow-md); }

/* Off-window marker — the ticket exists but its range is outside this period. */
.gantt-offwin{ position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  display:inline-flex;align-items:center;gap:4px;padding:3px 9px;
  border:1px dashed var(--border);border-radius:var(--mk-radius-pill);
  background:var(--bg-1);color:var(--fg-3);cursor:pointer;
  font:600 10.5px/1 var(--mk-font-ui); }
.gantt-offwin:hover{ border-color:var(--accent);color:var(--accent-text,var(--accent)); }
.gantt-offwin .mi{ font-size:13px; }
.gantt-offwin.bef{ inset-inline-start:6px; }
.gantt-offwin.aft{ inset-inline-end:6px; }
.gantt-row-off{ opacity:.85; }
/* Period stepper + picker (Week/Month/Quarter/Year navigation). */
.gantt-period{ display:inline-flex;align-items:center;gap:2px; }
.gantt-step{ width:30px;height:30px;border-radius:8px;border:1px solid var(--border);
  background:var(--bg-input);color:var(--fg-2);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  transition:border-color var(--mk-t-fast),color var(--mk-t-fast); }
.gantt-step:hover{ border-color:var(--accent);color:var(--accent-text); }
.gantt-step .mi{ font-size:18px; }
.gantt-period-lbl{ display:inline-flex;align-items:center;gap:4px;min-width:124px;justify-content:center;
  height:30px;padding:0 12px;border-radius:8px;border:1px solid var(--border);background:var(--bg-input);
  font:600 12.5px var(--mk-font-ui);color:var(--fg-1);cursor:pointer;
  transition:border-color var(--mk-t-fast); }
.gantt-period-lbl:hover{ border-color:var(--accent); }
.gantt-period-lbl .mi{ font-size:16px;color:var(--fg-3); }
.gantt-period-pop{ position:fixed;z-index:1200;min-width:160px;
  background:var(--bg-1);border:1px solid var(--border);border-radius:var(--mk-radius-md);
  box-shadow:var(--shadow-lg);padding:6px; }
.gantt-period-pop-h{ font:700 10px var(--mk-font-ui);letter-spacing:.08em;text-transform:none;
  color:var(--fg-3);padding:5px 8px 7px; }
.gantt-period-opt{ display:block;width:100%;text-align:start;border:0;background:transparent;cursor:pointer;
  padding:8px 10px;border-radius:7px;font:600 12.5px var(--mk-font-ui);color:var(--fg-1);
  transition:background var(--mk-t-fast); }
.gantt-period-opt:hover{ background:var(--bg-2); }
.gantt-period-opt.on{ background:var(--accent-soft);color:var(--accent-text); }
.gantt-bar-fill{ position:absolute;inset-inline-start:0;top:0;bottom:0;
  background:rgba(255,255,255,.22);pointer-events:none; }
.gantt-bar.done{ background:var(--mk-success); }
.gantt-bar.review{ background:#A855F7; }
.gantt-bar.progress{ background:var(--accent); }
.gantt-bar.backlog{ background:var(--fg-3); }
.gantt-bar.backlog .gantt-bar-l{ color:#fff; }

/* ── VERTICAL gantt (B44 C11) — a true vertical timeline: dates run top→bottom
   on the left axis, each ticket is a labeled card hanging at its date range;
   overlapping tickets are packed into adjacent columns. Mobile-portrait friendly. */
/* B54 — the orientation segment is gone (it is a breakpoint override now), so
   `.gantt-orient-seg` went with it. */
.gantt-v{ min-width:0; }
.gantt-vbody{ display:flex;align-items:stretch;min-height:540px; }
.gantt-vaxis{ flex:0 0 56px;width:56px;display:flex;flex-direction:column;
  background:var(--bg-2);border-inline-end:1px solid var(--divider); }
.gantt-vtick{ display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  min-height:0;padding:2px;border-top:1px solid var(--divider); }
.gantt-vtick:first-child{ border-top:0; }
.gantt-vtick.wknd{ background:color-mix(in srgb,var(--fg-3) 7%,transparent); }
.gantt-vtick.today{ background:color-mix(in srgb,var(--accent) 12%,transparent); }
.gantt-vtick .gh-dow{ font:600 9px var(--mk-font-ui);color:var(--fg-3); }
.gantt-vtick .gh-date{ font:700 11px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.gantt-vtick.today .gh-date{ color:var(--accent-text); }
.gantt-vplot{ position:relative;flex:1;min-width:0; }
/* Audit A — every column keeps a readable width (a card title was being cut to
   13px on a phone once a project and a parent ticket were both expanded); when
   the columns outgrow the screen the chart scrolls sideways inside .gantt-wrap,
   which already scrolls both ways. */
.gantt-v .gantt-vplot{ min-width:calc(var(--v-lanes,1) * 96px); }
.gantt-v .gantt-vfocus-track{ min-width:calc(var(--v-lanes,1) * 96px); }
.gantt-vgrid{ position:absolute;inset:0;display:flex;flex-direction:column;pointer-events:none; }
.gantt-vgrid span{ border-top:1px solid var(--divider); }
.gantt-vgrid span:first-child{ border-top:0; }
.gantt-vgrid span.wknd{ background:color-mix(in srgb,var(--fg-3) 5%,transparent); }
.gantt-vgrid span.today{ background:color-mix(in srgb,var(--accent) 8%,transparent); }
.gantt-vcard{ position:absolute;overflow:hidden;display:flex;min-height:38px;
  border-radius:10px;background:var(--bg-1);border:1px solid var(--divider);
  box-shadow:var(--shadow-sm);cursor:pointer;z-index:2;
  transition:box-shadow var(--mk-t-fast),border-color var(--mk-t-fast); }
.gantt-vcard:hover{ box-shadow:var(--shadow-md);border-color:var(--vc);z-index:4; }
.gantt-vcard.done{ --vc:var(--mk-success); }
.gantt-vcard.review{ --vc:#A855F7; }
.gantt-vcard.progress{ --vc:var(--accent); }
.gantt-vcard.backlog{ --vc:var(--fg-3); }
.gantt-vcard-stripe{ flex:0 0 4px;background:var(--vc); }
.gantt-vcard-in{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;padding:6px 8px; }
.gantt-vcard-hd{ display:flex;align-items:center;gap:5px; }
.gantt-vcard-id{ font:600 10px var(--mk-font-mono);color:var(--fg-3); }
/* B55 (Pablo: "the priority in the timeline can be at the bottom above the
   avatar, the ticket type chip could also take some space at the bottom") — type,
   priority and avatar are ONE bottom row now, so the head is just the key and the
   title owns the middle. The chip keeps the round-wash grammar from B51-25. */
.gantt-vcard-ft{ margin-top:auto;display:flex;align-items:center;gap:5px;padding-top:3px; }
.gantt-vcard-ft .gantt-type{ font-size:15px;color:var(--vc);flex:0 0 auto; }
/* B57 (Pablo: "the tag for the priority has a missalignment between the circle and
   the icon") — ROOT CAUSE: this variant is a <button>, and the base rule's
   `place-items:center` was fighting the UA's own button padding + baseline
   alignment, which pushed the 14px glyph a pixel low and right inside the 20px
   disc. Resetting the button box and centring the glyph explicitly fixes it. */
.gantt-vcard-ft .gantt-bar-prio-box{ position:static;transform:none;
  width:20px;height:20px;border-radius:999px;border:0;box-shadow:none;flex:0 0 auto;
  padding:0;margin:0;display:grid;place-items:center;line-height:0;appearance:none;
  background:color-mix(in srgb,currentColor 13%,transparent); }
.gantt-vcard-ft .gantt-bar-prio-box .mi{ font-size:14px;line-height:1;display:block; }
/* the avatar closes the row on the trailing edge */
.gantt-vcard-ft .gantt-bar-who{ margin-inline-start:auto;flex:0 0 auto; }
.gantt-vcard-tt{ font:600 12px var(--mk-font-ui);color:var(--fg-1);line-height:1.25;
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical; }
.gantt-vnd{ border-top:1px solid var(--divider); }
.gantt-vnd-list{ display:flex;flex-wrap:wrap;gap:8px;padding:10px 12px; }
.gantt-vnd-card{ display:flex;align-items:center;gap:7px;min-width:180px;flex:1 1 220px;max-width:300px;
  padding:8px 10px;border:1px solid var(--divider);border-radius:10px;background:var(--bg-1);
  box-shadow:var(--shadow-sm);cursor:pointer; }
.gantt-vnd-card .gantt-type{ font-size:16px;color:var(--fg-2);flex:0 0 auto; }
.gantt-vnd-card .gantt-vcard-in{ padding:0; }
.gantt-vnd-chip{ margin-inline-start:auto;display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;
  padding:3px 8px;border-radius:var(--mk-radius-pill);background:var(--bg-2);
  border:1px dashed var(--border);color:var(--fg-3);font:600 10px var(--mk-font-ui); }
.gantt-vnd-chip .mi{ font-size:13px; }
/* B50-01 — the vertical timeline's chip is a real button: schedule from today. */
.gantt-vnd-chip{ cursor:pointer; }
.gantt-vnd-chip:hover{ border-color:var(--accent);color:var(--accent-text,var(--accent));background:var(--accent-soft); }
@media (pointer:coarse){ .gantt-vnd-chip{ min-height:44px;padding:3px 12px; } }
/* B50-02 — an open-ended card in the vertical timeline fades out downwards and
   loses its bottom radius, the same grammar as the horizontal open bar. */
.gantt-vcard-open{ border-bottom-left-radius:0;border-bottom-right-radius:0;
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - 42px),transparent 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - 42px),transparent 100%); }

/* No-due-date group (F1) — a header band + rows with a "Not scheduled" chip
   instead of a bar. */
.gantt-group-h{ display:flex;align-items:center;gap:7px;
  padding:9px 14px;background:var(--bg-2);border-bottom:1px solid var(--divider);
  font:600 10.5px var(--mk-font-ui);letter-spacing:.06em;text-transform:none;color:var(--fg-3); }
.gantt-group-h .mi{ font-size:15px; }
.gantt-row-nodue{ opacity:.92; }
/* B50-01 — the chip is a hint now, not the only affordance: the whole track is a
   scheduling surface. Keep it clickable-looking and let pointer events through to
   the track so a click anywhere (including on the chip) schedules. */
.gantt-nodue-chip{ position:absolute;top:50%;inset-inline-start:12px;transform:translateY(-50%);
  display:inline-flex;align-items:center;gap:6px;z-index:2;pointer-events:none;
  transition:opacity var(--mk-t-fast);
  padding:4px 11px;border-radius:var(--mk-radius-pill);
  background:var(--bg-1);border:1px dashed var(--border);color:var(--fg-3);
  font:600 11px var(--mk-font-ui); }
.gantt-nodue-chip .mi{ font-size:14px; }
/* B65 W12 (065-107) — the unscheduled mark is SLIM now: no group band above it, the
   row sits with its siblings, so the mark only has to say "no dates yet". */
.gantt-row-nodue{ min-height:40px; }
.gantt-row-nodue .gantt-nodue-chip{ padding:2px 8px;gap:4px;font:600 10px var(--mk-font-ui);border-style:dashed; }
.gantt-row-nodue .gantt-nodue-chip .mi{ font-size:12px; }
/* Vertical chart: an unscheduled ticket is a slim column after the plot — its key
   and the mark written sideways, the schedule button on top. No share of the width. */
.gantt-vslim{ display:flex;flex:0 0 auto;border-inline-start:1px solid var(--divider);background:var(--bg-2); }
.gantt-vslim-col{ flex:0 0 30px;width:30px;display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:6px 0;border-inline-end:1px dashed var(--divider);cursor:pointer; }
.gantt-vslim-col:hover{ background:color-mix(in srgb,var(--accent) 7%,transparent); }
.gantt-vslim-sched{ display:grid;place-items:center;width:24px;height:24px;padding:0;border:1px dashed var(--border);
  border-radius:var(--mk-radius-pill);background:var(--bg-1);color:var(--fg-3);cursor:pointer; }
.gantt-vslim-sched .mi{ font-size:14px; }
.gantt-vslim-sched:hover{ border-color:var(--accent);color:var(--accent-text,var(--accent)); }
.gantt-vslim-l{ writing-mode:vertical-rl;font:600 10px var(--mk-font-ui);color:var(--fg-3);white-space:nowrap; }
.gantt-vslim-l b{ font:600 10px var(--mk-font-mono);color:var(--fg-2); }
@media (pointer:coarse){ .gantt-vslim-col{ flex-basis:44px;width:44px; } .gantt-vslim-sched{ width:36px;height:36px; } }
/* the focus note lines up with the plot only — the slim strip is not part of it */
.gantt-v .gantt-vfocus-row::after{ content:'';flex:0 0 auto;width:calc(var(--v-slim-n,0) * 31px); }
@media (pointer:coarse){ .gantt-v .gantt-vfocus-row::after{ width:calc(var(--v-slim-n,0) * 45px); } }

/* B65 W12 (065-104) — dependency dots on a hovered bar's ends + the drag guide. */
.gantt-link-hud{ position:fixed;inset:0;pointer-events:none;z-index:240;opacity:0;transition:opacity var(--mk-t-fast); }
.gantt-link-hud.on{ opacity:1; }
.gantt-link-dot{ position:fixed;width:14px;height:14px;margin:-7px 0 0 -7px;padding:0;border-radius:50%;
  border:2px solid var(--accent);background:var(--bg-1);box-shadow:var(--shadow-sm);cursor:crosshair;
  pointer-events:none;transition:transform var(--mk-t-fast),background var(--mk-t-fast); }
.gantt-link-hud.on .gantt-link-dot{ pointer-events:auto; }
.gantt-link-dot[hidden]{ display:none; }
.gantt-link-dot:hover,.gantt-link-hud.is-dragging .gantt-link-dot{ transform:scale(1.25);background:var(--accent); }
.gantt-link-dot::after{ content:'';position:absolute;inset:-9px; }  /* a bigger hit area than the dot */
@media (pointer:coarse){ .gantt-link-dot{ width:22px;height:22px;margin:-11px 0 0 -11px; } }
.gantt-link-guide{ position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:2450;overflow:visible; }
.gantt-link-guide line{ stroke:var(--accent);stroke-width:2;stroke-dasharray:6 4;stroke-linecap:round; }
.gantt-link-guide circle{ fill:var(--accent); }
html.gantt-linking, html.gantt-linking *{ cursor:crosshair !important; }
.gantt-link-over.gantt-row .gantt-bar, .gantt-link-over.gantt-row-nodue .gantt-track, .gantt-vcard.gantt-link-over, .gantt-vslim-col.gantt-link-over{
  outline:2px solid var(--accent);outline-offset:2px; }
.gantt-link-src .gantt-bar, .gantt-vcard.gantt-link-src{ box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent); }
/* Range selector reuses the shared .seg styling. */

/* Tickets activity feed inside the detail drawer */
.dwr-feed{ margin-top:4px; }

/* ═══ SERVICES · BACKEND tabs (Applications · Services · Entities) ════ */
.be-tab-view{ display:none; }
.page-view[data-view="services-backend"]:not([data-be-tab]) .be-tab-view[data-be-tab="services"],
.page-view[data-view="services-backend"][data-be-tab="services"] .be-tab-view[data-be-tab="services"],
.page-view[data-view="services-backend"][data-be-tab="applications"] .be-tab-view[data-be-tab="applications"],
.page-view[data-view="services-backend"][data-be-tab="entities"] .be-tab-view[data-be-tab="entities"]{
  display:block;animation:secIn .28s var(--mk-ease) both;
}
/* B9-05 defensive guarantee (Pablo 2026-06-22 — "blank page on backend mobile
   portrait"). Could not reproduce in-app (every tab + bottom-bar tap keeps a
   panel visible), so the report is a stale-cache/published-view artifact — but
   make a blank page STRUCTURALLY impossible: if data-be-tab ever holds a value
   that matches NO panel, fall back to showing the Services panel rather than
   hiding all three. */
.page-view[data-view="services-backend"][data-be-tab]:not([data-be-tab="services"]):not([data-be-tab="applications"]):not([data-be-tab="entities"]) .be-tab-view[data-be-tab="services"]{
  display:block;animation:secIn .28s var(--mk-ease) both;
}
.app-card .app-top{ display:flex;align-items:center;gap:10px;flex-wrap:wrap; }
.app-card .app-ic{ width:38px;height:38px;border-radius:11px;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;color:#fff; }
.app-card .app-ic .mi{ font-size:20px; }
.app-card .app-cat{ font:600 11px var(--mk-font-ui);color:var(--fg-3);
  letter-spacing:.03em;text-transform:none; }
.app-card .app-top .pill{ margin-inline-start:auto; }
.app-card .app-desc{ font:500 12.5px var(--mk-font-ui);color:var(--fg-2);line-height:1.5;text-wrap:pretty; }
.app-card .app-foot{ display:inline-flex;align-items:center;gap:6px;
  font:600 12px var(--mk-font-ui);color:var(--fg-3); }
.app-card .app-foot .mi{ font-size:16px; }
.ent-grid{ grid-template-columns:repeat(auto-fill,minmax(min(100%,220px),1fr)); }
.ent-card .ent-top{ display:flex;align-items:center;gap:10px; }
.ent-card .ent-ic{ width:36px;height:36px;border-radius:10px;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-text); }
.ent-card .ent-stats{ display:flex;gap:18px; }
.ent-card .ent-stat{ display:flex;flex-direction:column;gap:1px; }
.ent-card .es-v{ font:700 16px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.ent-card .es-l{ font:600 10px var(--mk-font-ui);color:var(--fg-3);text-transform:none;letter-spacing:.04em; }

/* ═══ Entity cards — clickable + foundational (Pablo B27 C2) ═══ */
.ent-card{ cursor:pointer;transition:border-color var(--mk-t-fast),transform var(--mk-t-fast),box-shadow var(--mk-t-fast);position:relative; }
.ent-card:hover{ border-color:var(--accent);transform:translateY(-2px);box-shadow:0 8px 24px rgba(13,37,48,.10); }
.ent-card:focus-visible{ outline:2px solid var(--accent);outline-offset:2px; }
.ent-card .ent-open{ margin-inline-start:auto;font-size:20px;color:var(--fg-3);transition:transform var(--mk-t-fast),color var(--mk-t-fast); }
.ent-card:hover .ent-open{ color:var(--accent);transform:translateX(2px); }
html[dir="rtl"] .ent-card .ent-open{ transform:scaleX(-1); }
html[dir="rtl"] .ent-card:hover .ent-open{ transform:scaleX(-1) translateX(2px); }
.ent-card .ent-desc{ font:500 12px/1.5 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty; }
.ent-core-badge{ display:inline-flex;align-items:center;gap:3px;padding:2px 7px 2px 5px;border-radius:999px;
  font:700 9.5px var(--mk-font-ui);letter-spacing:.05em;text-transform:none;
  background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--accent) 45%,#7b5bd6));color:var(--accent-fg); }
.ent-core-badge .mi{ font-size:12px; }
.ent-card-core{ border-color:color-mix(in srgb,var(--accent) 30%,var(--border)); }
.ent-card-core .ent-ic{ background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--accent) 45%,#7b5bd6));color:var(--accent-fg); }

/* ═══ Entity definition panel (docks like .filter-panel) ═══ */
/* B46 — width intentionally NOT set here: panels.css loads later and owns the
   single `--mk-panel-w` width for every slide-in panel (P6-04). The old
   `width:min(460px,100vw)` was dead code that read like a live 460px rule. */
.ent-panel{ display:flex;flex-direction:column; }
.ent-panel-hd .ent-hd-ic{ font-size:20px;color:var(--accent); }
.ent-panel-hd .panel-hd-l{ gap:9px; }
/* B34 C16 — compressed breadcrumb title ("Mocca › +3 › Field").
   B50-11 — the +n is a real, styled, EXPANDABLE pill; the elided segments are in
   the DOM (hidden) and unfold in place. */
.ent-panel-hd .ent-crumb{ display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden;flex-wrap:nowrap; }
.ent-crumb .ec-seg{ min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto; }
.ent-crumb .ec-cur{ flex:1 1 auto;color:var(--fg-1); }
.ent-crumb .ec-seg:not(.ec-cur){ color:var(--fg-3);font-weight:600; }
.ent-crumb .ec-sep{ flex:0 0 auto;color:var(--fg-3);opacity:.6;font-weight:600; }
.ent-crumb .ec-mid{ display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden; }
.ent-crumb .ec-mid[hidden]{ display:none; }
.ec-more{ flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  min-width:26px;height:20px;padding:0 7px;border-radius:999px;cursor:pointer;
  border:1px solid color-mix(in srgb,var(--accent) 34%,transparent);
  background:var(--accent-soft);color:var(--accent-text,var(--accent));
  font:700 10.5px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums;
  transition:background var(--mk-t-fast),border-color var(--mk-t-fast),transform var(--mk-t-fast); }
.ec-more:hover{ background:color-mix(in srgb,var(--accent) 18%,transparent);border-color:var(--accent); }
.ec-more:active{ transform:scale(.94); }
.ec-more:focus-visible{ outline:2px solid var(--accent);outline-offset:2px; }
/* Expanded: the pill becomes a quiet "collapse" affordance so the row doesn't
   read as if there were still something hidden. */
.ec-more[aria-expanded="true"]{ background:transparent;border-style:dashed;color:var(--fg-3); }
.ec-more[aria-expanded="true"]::after{ content:"\2212";font-size:11px; }
.ec-more[aria-expanded="true"]{ font-size:0;gap:0; }
@media (pointer:coarse){ .ec-more{ height:28px;min-width:34px; } }
.ent-panel-desc{ padding:12px 16px 0;font:500 12.5px/1.55 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty; }
.ent-metabar{ display:flex;gap:20px;padding:12px 16px;border-bottom:1px solid var(--border); }
.ent-metabar span{ font:600 11px var(--mk-font-ui);color:var(--fg-3);text-transform:none;letter-spacing:.04em; }
.ent-metabar b{ font:700 15px var(--mk-font-ui);color:var(--fg-1);margin-inline-end:4px;font-variant-numeric:tabular-nums;text-transform:none; }
.ent-tabs{ margin:0;padding:6px 12px 0;border-bottom:1px solid var(--border);flex-shrink:0; }
.ent-panel-body{ padding:12px 14px 20px; }

/* Fields — a nestable tree; children of form / collection<form> fields
   indent and collapse (Pablo B27: "fields can have children"). */
.ent-fields{ display:flex;flex-direction:column;gap:2px; }
.ent-field{ border-radius:9px; }
.ent-field-row{ display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:9px;
  padding-inline-start:calc(10px + var(--d,0) * 18px); }
.ent-field.is-nested > .ent-field-row{ background:color-mix(in srgb,var(--accent) 5%,transparent); }
.ent-field.has-ch > .ent-field-row{ cursor:pointer; }
.ent-field.has-ch > .ent-field-row:hover{ background:var(--bg-input); }
.ent-caret{ font-size:17px;color:var(--fg-3);transition:transform var(--mk-t-fast);flex:0 0 auto; }
.ent-field.open > .ent-field-row > .ent-caret{ transform:rotate(90deg); }
html[dir="rtl"] .ent-caret{ transform:scaleX(-1); }
html[dir="rtl"] .ent-field.open > .ent-field-row > .ent-caret{ transform:rotate(-90deg); }
.ent-caret-sp{ width:17px;flex:0 0 auto; }
.ent-f-ic{ font-size:17px;color:var(--accent-text);flex:0 0 auto; }
.ent-f-nm{ font:600 13px var(--mk-font-ui);color:var(--fg-1); }
.ent-f-type{ font:600 11px var(--mk-font-mono);color:var(--fg-3);padding:1px 7px;border-radius:6px;background:var(--bg-input); }
.ent-f-req{ font:700 9px var(--mk-font-ui);letter-spacing:.05em;text-transform:none;color:var(--mk-err,#c0392b);
  padding:1px 6px;border-radius:5px;background:var(--mk-err-soft,#fce8e8); }
.ent-f-def{ font:600 11px var(--mk-font-mono);color:var(--fg-3);margin-inline-start:auto; }
.ent-f-meta{ font:500 11px/1.45 var(--mk-font-ui);color:var(--fg-3);padding:0 10px 4px calc(35px + var(--d,0) * 18px);text-wrap:pretty; }
.ent-children{ display:none;position:relative; }
.ent-field.open > .ent-children{ display:block;animation:secIn .2s var(--mk-ease) both; }
/* continuous indent guide rail per level */
.ent-children::before{ content:'';position:absolute;top:0;bottom:4px;
  inset-inline-start:calc(18px + var(--d,0) * 18px);width:1.5px;background:var(--border); }

/* Permissions — role grid */
.ent-perms{ width:100%;border-collapse:collapse;font:500 12.5px var(--mk-font-ui); }
.ent-perms th{ font:700 10px var(--mk-font-ui);text-transform:none;letter-spacing:.04em;color:var(--fg-3);
  padding:8px 6px;text-align:center;border-bottom:1px solid var(--border); }
.ent-perms th:first-child{ text-align:start; }
.ent-perms td{ padding:9px 6px;border-bottom:1px solid var(--border); }
.ent-perms .ent-cap{ color:var(--fg-1);font-weight:600; }
.ent-pm{ text-align:center; }
.ent-pm .mi{ font-size:17px; }
.ent-pm.ok .mi{ color:var(--mk-ok,#2f9e63); }
.ent-pm.no .mi{ color:var(--fg-4,#b8c2c6); }
.ent-pm.cond .mi{ color:var(--mk-warn,#c78a1e); }

/* Conditions — validations + quick filters */
.ent-conds{ display:flex;flex-direction:column;gap:8px; }
.ent-cond{ display:flex;gap:9px;align-items:flex-start;padding:10px 12px;border-radius:10px;border:1px solid var(--border);background:var(--bg-1); }
.ent-cond > .mi{ font-size:17px;color:var(--accent-text);flex:0 0 auto;margin-top:1px; }
.ent-cond-t{ display:flex;flex-direction:column;gap:3px;min-width:0; }
.ent-cond-t b{ font:600 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ent-cond-t code{ font:600 11.5px var(--mk-font-mono);color:var(--fg-3); }

/* ═══ B28 C6 — entity cards uniform + collection-based definition form ═══ */
/* Pablo: no Core badge / no differentiation — give EVERY card the nicer
   gradient icon + faint accent border the foundational ones had. */
.ent-card{ border-color:color-mix(in srgb,var(--accent) 20%,var(--border)); }
.ent-card .ent-ic{ background:linear-gradient(135deg,var(--accent),color-mix(in srgb,var(--accent) 45%,#7b5bd6));color:var(--accent-fg); }

/* the panel is now a slide stack (matches the Filters panel) */
.ent-panel .ent-slide-stack{ position:relative;flex:1;min-height:0;overflow:hidden; }
.ent-slide{ position:absolute;inset:0;display:flex;flex-direction:column;min-height:0;background:var(--bg-1); }
.ent-slide-root{ z-index:1; }
.ent-slide-pushed{ z-index:2;transform:translateX(100%);transition:transform .3s cubic-bezier(.32,.72,.28,1);box-shadow:-16px 0 40px rgba(13,37,48,.14); }
html[dir="rtl"] .ent-slide-pushed{ transform:translateX(-100%); }
.ent-slide-pushed.open{ transform:translateX(0); }
/* Audit A11 — the RTL "closed" rule above is (0,2,1) and out-specified the plain `.open` one, so in Arabic the slide stayed parked off-screen. */
html[dir="rtl"] .ent-slide-pushed.open{ transform:translateX(0); }
.ent-slide .ent-panel-body{ flex:1;min-height:0;overflow-y:auto; }

/* three stacked Collections (like Actions/States/Context/Effects) */
.ent-coll{ margin-bottom:20px; }
/* ═══ B51-07 / B51-22 · the CONFIGURE row ═════════════════════════
   "here we should see a button to 'Configure' the permissions which opens a
   panel" · "it can simply be a button to configure that opens the modal". One row
   shape for both, matching the panel's other openable rows: full-width, hairline,
   name over a computed summary, the CTA + chevron trailing. No box, no card. */
.ent-cfg-row{ display:flex;align-items:center;gap:11px;width:100%;box-sizing:border-box;
  padding:11px 12px;border:1px solid var(--border);border-radius:var(--mk-radius-md,12px);
  background:var(--bg-1);cursor:pointer;text-align:start;
  transition:border-color var(--mk-t-fast),background var(--mk-t-fast); }
.ent-cfg-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border));background:var(--bg-2); }
.ent-cfg-ic{ font-size:19px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.ent-cfg-txt{ display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto; }
.ent-cfg-nm{ font:700 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ent-cfg-sub{ font:500 11px/1.45 var(--mk-font-ui);color:var(--fg-3);text-wrap:pretty; }
.ent-cfg-go{ display:inline-flex;align-items:center;gap:2px;flex:0 0 auto;color:var(--fg-3); }
.ent-cfg-cta{ font:700 11px var(--mk-font-ui);color:var(--accent-text,var(--accent)); }
.ent-cfg-go .mi{ font-size:18px; }
[dir="rtl"] .ent-cfg-go .mi{ transform:scaleX(-1); }
@media (pointer:coarse){ .ent-cfg-row{ min-height:60px; } }
/* B51-07 — the "add another" button at the foot of a nested slide's list. */
.ent-add-btn{ display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  padding:8px 13px;border-radius:999px;border:1px dashed var(--border);
  background:transparent;color:var(--fg-2);cursor:pointer;font:600 11.5px var(--mk-font-ui); }
.ent-add-btn:hover{ border-color:var(--accent);color:var(--accent-text,var(--accent));background:var(--accent-soft);border-style:solid; }
.ent-add-btn .mi{ font-size:16px; }
@media (pointer:coarse){ .ent-add-btn{ min-height:44px; } }
.ent-coll-hd{ display:flex;align-items:center;gap:8px;margin-bottom:9px; }
.ent-coll-ic{ font-size:18px;color:var(--accent-text); }
.ent-coll-t{ font:700 13px var(--mk-font-ui);color:var(--fg-1);flex:1; }
.ent-coll-add{ display:inline-flex;align-items:center;gap:4px;padding:5px 10px;border-radius:8px;
  border:1px dashed color-mix(in srgb,var(--accent) 40%,var(--border));background:none;color:var(--accent-text);
  font:600 11.5px var(--mk-font-ui);cursor:pointer; }
.ent-coll-add:hover{ background:var(--accent-soft); }
.ent-coll-add .mi{ font-size:15px; }
.ent-coll-body{ display:flex;flex-direction:column;gap:6px; }
.ent-coll-empty{ font:500 12px var(--mk-font-ui);color:var(--fg-3);padding:6px 2px; }
.ent-row{ cursor:pointer; }
.ent-row.drag-over{ outline:2px dashed var(--accent);outline-offset:1px;border-radius:9px; }
.ent-row.dragging{ opacity:.5; }
.ent-type-chip{ white-space:nowrap; }
.ent-pm-chips{ display:inline-flex;gap:3px;margin-inline-start:auto; }
.ent-pm-chip{ width:18px;height:18px;border-radius:5px;display:grid;place-items:center;font:700 9.5px var(--mk-font-ui); }
.ent-pm-chip.ok{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 18%,transparent);color:var(--mk-ok,#2f9e63); }
.ent-pm-chip.cond{ background:color-mix(in srgb,var(--mk-warn,#c98a2b) 20%,transparent);color:var(--mk-warn,#c98a2b); }
.ent-pm-chip.no{ background:var(--bg-3,#eef2f4);color:var(--fg-3); }
.ent-cond-col{ display:flex;flex-direction:column;gap:1px;min-width:0;flex:1;text-align:start; }
.ent-cond-rule{ font-size:10.5px;color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }

/* the standard, type-keyed field form */
.ent-panel-body .ent-form-lbl{ font:700 10.5px var(--mk-font-ui);text-transform:none;letter-spacing:.05em;color:var(--fg-3);margin:13px 0 5px; }
.ent-input{ width:100%;padding:8px 11px;border-radius:9px;border:1px solid var(--border);background:var(--bg-input);color:var(--fg-1);font:500 13px var(--mk-font-ui);outline:none; }
.ent-input:focus{ border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft); }
.ent-form-row2{ display:flex;gap:10px; }
.ent-field-col{ flex:1;min-width:0; }
.ent-field-col .ent-form-lbl{ margin-top:0; }
.ent-toggle{ display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:13px;cursor:pointer; }
.ent-toggle-l{ font:600 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ent-sw{ width:38px;height:22px;border-radius:999px;background:var(--bg-3,#d8dfe2);position:relative;transition:background var(--mk-t-fast);flex:0 0 auto; }
.ent-sw-k{ position:absolute;top:2px;inset-inline-start:2px;width:18px;height:18px;border-radius:999px;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:transform var(--mk-t-fast); }
.ent-sw.on{ background:var(--accent); }
.ent-sw.on .ent-sw-k{ transform:translateX(16px); }
html[dir="rtl"] .ent-sw.on .ent-sw-k{ transform:translateX(-16px); }
.ent-cs{ margin-top:2px; }
.ent-opts{ display:flex;flex-direction:column;gap:6px; }
.ent-opt{ display:flex;align-items:center;gap:8px;padding:6px 8px 6px 11px;border-radius:8px;border:1px solid var(--border);background:var(--bg-1); }
.ent-opt-t{ flex:1;font:500 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ent-opt-x{ width:22px;height:22px;border-radius:6px;border:0;background:none;color:var(--fg-3);cursor:pointer;display:grid;place-items:center; }
.ent-opt-x:hover{ background:var(--mk-err-soft,#fce8e8);color:var(--mk-err,#c0392b); }
.ent-opt-x .mi{ font-size:15px; }
.ent-opt-add{ display:flex;gap:6px; }
.ent-opt-add .ent-input{ flex:1; }
.ent-opt-addb{ width:34px;border-radius:9px;border:1px solid var(--border);background:var(--bg-input);color:var(--accent-text);cursor:pointer;display:grid;place-items:center; }
.ent-opt-addb:hover{ border-color:var(--accent); }
.ent-subfields-box{ border:1px solid var(--border);border-radius:11px;padding:8px;background:color-mix(in srgb,var(--accent) 4%,transparent); }
.ent-subfields{ gap:6px;margin-bottom:8px; }
.ent-subadd{ width:100%;justify-content:center; }
.ent-perm-role{ display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 0; }
.ent-perm-role-nm{ font:600 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ent-tri{ display:inline-flex;gap:3px; }
.ent-tri-b{ width:32px;height:28px;border-radius:8px;border:1px solid var(--border);background:var(--bg-input);color:var(--fg-3);cursor:pointer;display:grid;place-items:center; }
.ent-tri-b .mi{ font-size:16px; }
.ent-tri-b.on.allow{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 18%,transparent);border-color:var(--mk-ok,#2f9e63);color:var(--mk-ok,#2f9e63); }
.ent-tri-b.on.cond{ background:color-mix(in srgb,var(--mk-warn,#c98a2b) 20%,transparent);border-color:var(--mk-warn,#c98a2b);color:var(--mk-warn,#c98a2b); }
.ent-tri-b.on.deny{ background:var(--bg-3,#eef2f4);border-color:var(--fg-3);color:var(--fg-2); }
.ent-permex-cap{ margin:6px 0 4px;padding:8px 10px;border:1px solid var(--border);border-radius:12px;background:color-mix(in srgb,var(--bg-input) 55%,transparent); }
.ent-permex-cap-h{ display:flex;align-items:center;gap:7px;font:700 12px var(--mk-font-ui);color:var(--fg-1);margin-bottom:2px; }
.ent-permex-cap-h .mi{ font-size:16px;color:var(--fg-3); }
.ent-permex-cap .ent-perm-role{ padding:5px 0; }
.ent-form-note{ margin-top:10px;font:500 11.5px/1.5 var(--mk-font-ui);color:var(--fg-3);text-wrap:pretty; }

/* ════ B34 C18+C21 — entity condition-tree builder ════ */
.ent-cond-btn-wrap{ margin-bottom:14px; }
.ent-cond-open-btn{ display:flex;align-items:center;gap:8px;width:100%;padding:10px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;background:var(--bg-1,#fff);cursor:pointer;text-align:start;transition:border-color .15s,background .15s; }
.ent-cond-open-btn:hover{ border-color:var(--accent);background:var(--bg-2,#f6f8fa); }
.ent-cond-open-btn>.mi{ font-size:18px;color:var(--accent);flex:none; }
.ent-cond-open-l{ flex:1;min-width:0;font:600 12.5px/1.35 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ent-cond-open-l.empty{ color:var(--fg-3);font-weight:500; }
.ent-cond-open-caret{ font-size:18px;color:var(--fg-3);flex:none; }
.ent-cond-quick{ margin-bottom:14px; }
.ent-cond-quick-chips{ display:flex;flex-wrap:wrap;gap:7px; }
.ent-cond-qf{ display:inline-flex;align-items:center;gap:5px;padding:6px 11px;border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;background:var(--bg-1,#fff);cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2);transition:border-color .15s,background .15s,color .15s; }
.ent-cond-qf:hover{ border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent); }
.ent-cond-qf .mi{ font-size:15px; }
.ent-cond-tree{ display:flex;flex-direction:column;gap:8px; }
/* B35 C2 — host for the SHARED Filters condition tree inside entity slides.
   The .fp-tree normally owns panel scroll; here the slide body scrolls, so
   the tree renders at natural height. */
.ent-cond-host{ display:flex;flex-direction:column;min-height:60px; }
.ent-cond-host .fp-tree{ flex:none;overflow:visible;min-height:0; }
.ent-cond-conj{ display:inline-flex;gap:0;border:1px solid var(--bd-1,#dfe4e8);border-radius:8px;overflow:hidden;align-self:flex-start;margin-bottom:2px; }
.ent-cond-conj-b{ padding:5px 14px;border:none;background:var(--bg-1,#fff);cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2);transition:background .15s,color .15s; }
.ent-cond-conj-b+.ent-cond-conj-b{ border-inline-start:1px solid var(--bd-1,#dfe4e8); }
.ent-cond-conj-b.on{ background:var(--accent);color:#fff; }
.ent-cond-row{ display:flex;align-items:center;gap:6px;flex-wrap:wrap; }
.ent-cond-row .ent-cs{ flex:1;min-width:120px; }
.ent-cond-row .ent-cond-op{ flex:0 0 auto;min-width:130px; }
.ent-cond-row .ent-cond-val{ flex:1;min-width:110px; }
.ent-cond-rm{ flex:none;width:30px;height:30px;display:grid;place-items:center;border:1px solid var(--bd-1,#dfe4e8);border-radius:8px;background:var(--bg-1,#fff);cursor:pointer;color:var(--fg-3);transition:border-color .15s,color .15s; }
.ent-cond-rm:hover{ border-color:var(--mk-danger,#d9534f);color:var(--mk-danger,#d9534f); }
.ent-cond-rm .mi{ font-size:16px; }
.ent-cond-group{ position:relative;border:1px dashed var(--bd-1,#dfe4e8);border-radius:10px;padding:10px 10px 10px 14px;background:color-mix(in srgb,var(--accent) 4%,transparent); }
.ent-cond-group-body{ display:flex;flex-direction:column;gap:8px; }
.ent-cond-group-rm{ position:absolute;top:8px;inset-inline-end:8px;z-index:1; }
.ent-cond-adds{ display:flex;gap:8px;flex-wrap:wrap;margin-top:2px; }
.ent-cond-add{ display:inline-flex;align-items:center;gap:5px;padding:7px 12px;border:1px dashed var(--bd-1,#cfd6dc);border-radius:8px;background:transparent;cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--accent);transition:border-color .15s,background .15s; }
.ent-cond-add:hover{ border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent); }
.ent-cond-add.ent-cond-add-grp{ color:var(--fg-2); }
.ent-cond-add .mi{ font-size:15px; }
.ent-cap-l{ display:inline-flex;align-items:center;gap:8px; }
.ent-cap-ic{ font-size:17px;color:var(--fg-3); }

/* ════ B29 — shared nested tree (C1 Routes + C4 Backend) ════ */
.be-tree-wrap{ padding:2px 0 24px; }
.nt-host{ display:block; }
.nt-root{ display:flex;flex-direction:column;gap:6px; }
.nt-children{ display:none;flex-direction:column;gap:6px;margin-top:6px;
  padding-inline-start:20px;position:relative; }
.nt-children.open{ display:flex; }
/* the continuous indent rail (opacity shifts per level, per standing spec) */
.nt-children::before{ content:'';position:absolute;inset-block:0;inset-inline-start:9px;width:2px;
  background:var(--border);border-radius:2px; }
.nt-node{ position:relative; }
.nt-box{
  display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:11px;
  border:1px solid var(--border);background:var(--bg-1);cursor:pointer;position:relative;
  transition:border-color var(--mk-t-fast),background var(--mk-t-fast);
}
.nt-box:hover{ border-color:var(--accent);background:var(--accent-soft); }
.nt-caret{ width:24px;height:24px;flex:0 0 auto;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;color:var(--fg-3);border-radius:50%; }
.nt-caret:hover{ background:var(--bg-input);color:var(--fg-1); }
/* B39 C18 — the chevron glyph is optically right-of-centre in its em box, so a
   square highlight read as misaligned; a centred circle + a glyph box that
   pins the arrow to the caret centre keeps the hover aligned with the arrow. */
/* B40 C11 — icon panel edit form */
#iconPanel [data-icp-edit]{ display:grid; }
body:not([data-env="staging"]) #iconPanel [data-icp-edit]{ display:none !important; }
.ic-edit-prev{ display:grid;place-items:center;padding:18px;border:1px dashed var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-2,#f7f9fa); }
.ic-node-ed{ border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;padding:9px 11px;display:flex;flex-direction:column;gap:7px; }
.ic-node-ed + .ic-node-ed{ margin-top:7px; }
.ic-node-ed-h{ display:flex;align-items:center;gap:8px; }
.ic-node-ed-h select{ width:auto;flex:0 0 auto; }
.ic-node-mini{ display:grid;place-items:center;width:30px;height:30px;border:1px solid var(--bd-1,#dfe4e8);border-radius:7px;background:var(--bg-1,#fff);margin-inline-start:auto; }
.ic-d-ta{ font:500 11px/1.5 var(--mk-font-mono);min-height:52px;resize:vertical; }
.ic-geo{ display:flex;gap:6px;flex-wrap:wrap; }
.ic-geo input{ width:64px;flex:0 0 auto; }
.ic-bind-row{ display:flex;align-items:center;gap:8px;flex-wrap:wrap; }
.ic-bind-ed{ display:flex;gap:6px;flex:1;min-width:0;flex-wrap:wrap; }
.ic-bind-ed select{ width:auto;flex:0 0 auto; }
.ic-bind-ed input{ flex:1;min-width:70px; }
/* B40 C22 — chat create panel */
.chc-kinds{ display:flex;gap:6px;flex-wrap:wrap; }
.chc-kind{ display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;background:var(--bg-1,#fff);cursor:pointer;font:600 12px/1 var(--mk-font-ui);color:var(--fg-2); }
.chc-kind .mi{ font-size:16px; }
.chc-kind.on{ border-color:var(--accent);color:var(--accent-text,var(--accent));background:color-mix(in srgb,var(--accent) 9%,transparent); }
.chc-people{ display:flex;flex-direction:column;gap:5px;margin-top:4px; }
.chc-person{ display:flex;align-items:center;gap:9px;padding:8px 11px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);cursor:pointer;font:600 12.5px/1 var(--mk-font-ui);color:var(--fg-1);text-align:start; }
.chc-person:hover{ border-color:var(--fg-3); }
.chc-person.on{ border-color:var(--accent);background:color-mix(in srgb,var(--accent) 7%,transparent); }
.chc-person .chc-chk{ margin-inline-start:auto;color:var(--accent-text,var(--accent));font-size:18px; }
.chc-search{ margin-bottom:2px; }
.wl-hint .mi{ font-size:14px;vertical-align:-2px;margin-inline-end:4px;color:var(--fg-3); }
/* B40 C21 (Pablo, repeat of B39 C18) — kill the residual optical offset: the
   caret is a flex-centred circle and the glyph an unconstrained block, so the
   arrow sits dead-centre of the hover circle at every zoom. */
.nt-caret{ display:flex;align-items:center;justify-content:center; }
.nt-caret .mi{ font-size:18px;transition:transform var(--mk-t-fast);line-height:1;width:auto;height:auto;display:block; }
.nt-caret.open .mi{ transform:rotate(90deg); }
html[dir="rtl"] .nt-caret .mi{ transform:rotate(180deg); }
html[dir="rtl"] .nt-caret.open .mi{ transform:rotate(90deg); }
.nt-caret-sp{ width:24px;flex:0 0 auto; }
.nt-ic{ width:28px;height:28px;flex:0 0 auto;display:grid;place-items:center;border-radius:8px;
  font-size:17px;background:var(--nt-tint,var(--accent-soft));color:var(--nt-tint-fg,var(--accent-text)); }
.nt-kind-app > .nt-box .nt-ic{ color:#fff;background:var(--nt-tint,var(--accent)); }
/* B32 C1 (verifier fix) — the IMAGE tile must beat the kind-app tint rule
   above: neutral soft tile, contained logo, regardless of node kind. */
.nt-root .nt-node > .nt-box .nt-ic.nt-ic-img{ background:var(--bg-2);border:1px solid var(--border); }
.nt-kind-service > .nt-box .nt-ic{ background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text); }
.nt-kind-param > .nt-box .nt-ic{ background:var(--bg-input);color:var(--fg-3); }
/* B63 W9 — Middleware's forms tree reuses the same nested-tree component;
   a form is app-level weight, a variant reads as a fork of it. */
.nt-kind-form > .nt-box .nt-ic{ color:#fff;background:var(--nt-tint,var(--accent)); }
.nt-kind-variant > .nt-box .nt-ic{ background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text); }
/* B63 W9 (149) — the Frontend route tree's level chip, ahead of the label.
   One colour per level, matching the approved sample (samples/w2/frontend.html);
   `cfg.levelChips` (set only on the routes tree) is what makes this render at
   all, so the Backend tree's app/service/entity rows are untouched. */
.nt-lv{
  display:inline-flex;align-items:center;height:18px;padding:0 6px;border-radius:5px;flex:0 0 auto;
  font:700 9.5px var(--mk-font-ui);letter-spacing:.06em;text-transform:uppercase;color:#fff;
}
.nt-lv-app{ background:#22526A; }
.nt-lv-domain{ background:#0E7C86; }
.nt-lv-sub{ background:transparent;color:#0E7C86;box-shadow:inset 0 0 0 1.5px #0E7C86; }
.nt-lv-section{ background:#6D5BD0; }
.nt-lv-page{ background:#B45309; }
.nt-lv-tab{ background:var(--fg-3); }
html[data-theme="dark"] .nt-lv-sub{ color:#4FD8CE;box-shadow:inset 0 0 0 1.5px #4FD8CE; }
.nt-label{ font:600 13px var(--mk-font-ui);color:var(--fg-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.nt-kind-app > .nt-box .nt-label{ font-size:14px;font-weight:700; }
.nt-path{ font:600 11.5px var(--mk-font-mono);color:var(--fg-3);background:var(--bg-input);padding:1px 7px;border-radius:6px;
  min-width:0;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:ltr; }
/* Audit A — the route's NAME is what you read; the path gives way first */
.nt-kind-route > .nt-box > .nt-label{ flex:0 0 auto;max-width:62%; }
/* C13 (Pablo B34) — on route rows the path + trailing chips sit on the RIGHT.
   B40 C9 — only the PATH takes the auto margin; the chips/actions that follow it
   must NOT declare their own auto margin (two autos split the free space and the
   chips ended up floating mid-row). */
.nt-kind-route > .nt-box .nt-path{ margin-inline-start:auto; }
.nt-kind-route > .nt-box .nt-path ~ .nt-chips,
.nt-kind-route > .nt-box .nt-path ~ .nt-acts,
.nt-kind-route > .nt-box .nt-path ~ .nt-go{ margin-inline-start:8px; }
.nt-badge{ margin-inline-start:6px;font:700 10px var(--mk-font-ui);color:var(--fg-3);background:var(--bg-input);padding:2px 7px;border-radius:999px;font-variant-numeric:tabular-nums; }
.nt-meta{ margin-inline-start:auto;font:600 11px var(--mk-font-mono);color:var(--fg-3);white-space:nowrap; }
/* B30 C11 (Pablo): per-row meta as right-aligned tag chips, aligned to the end. */
.nt-chips{ margin-inline-start:auto;display:flex;align-items:center;gap:5px;flex:0 0 auto; }
.nt-chip{ font:600 10.5px var(--mk-font-ui);color:var(--fg-2);background:var(--bg-input);border:1px solid var(--border);padding:2px 8px;border-radius:999px;white-space:nowrap; }
.nt-chips + .nt-acts,.nt-chips + .nt-go{ margin-inline-start:8px; }
.nt-go{ margin-inline-start:auto;font-size:18px;color:var(--fg-3);flex:0 0 auto; }
.nt-box:hover .nt-go{ color:var(--accent-text); }
.nt-acts{ margin-inline-start:auto;display:flex;gap:3px;flex:0 0 auto; }
.nt-meta + .nt-acts{ margin-inline-start:8px; }
.nt-act{ width:26px;height:26px;border-radius:7px;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;color:var(--fg-3); }
.nt-act:hover{ background:var(--accent-soft);color:var(--accent-text); }
.nt-del:hover{ background:color-mix(in srgb,var(--mk-err,#c0392b) 16%,transparent);color:var(--mk-err,#c0392b); }
.nt-act .mi{ font-size:15px; }
.nt-add-root{ margin-top:4px;width:100%;display:flex;align-items:center;justify-content:center;gap:6px;
  padding:9px;border-radius:11px;border:1px dashed color-mix(in srgb,var(--accent) 40%,var(--border));
  background:none;color:var(--accent-text);cursor:pointer;font:600 12.5px var(--mk-font-ui); }
.nt-add-root:hover{ border-style:solid;background:var(--accent-soft); }
.nt-add-root .mi{ font-size:17px; }
/* drag + drop cues */
.nt-node.nt-dragging{ opacity:.45; }
.nt-box.nt-drop-in{ border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 2px var(--accent) inset; }
.nt-box.nt-drop-before{ box-shadow:inset 0 2px 0 var(--accent); }
.nt-box.nt-drop-after{ box-shadow:inset 0 -2px 0 var(--accent); }
/* inline editor (routes) */
.nt-editor{ display:flex;flex-direction:column;gap:8px;padding:11px;border-radius:11px;
  border:1px solid var(--accent);background:var(--bg-1);box-shadow:0 8px 24px rgba(13,37,48,.1); }
.nt-ed-f{ display:flex;flex-direction:column;gap:4px; }
.nt-ed-f > span{ font:600 10.5px var(--mk-font-ui);color:var(--fg-3); }
.nt-ed-f select.ent-input{ appearance:auto; }
.nt-ed-acts{ display:flex;justify-content:flex-end;gap:7px;margin-top:2px; }
.nt-ed-acts button{ border-radius:8px;padding:6px 13px;font:600 12px var(--mk-font-ui);cursor:pointer;border:1px solid var(--border);background:var(--bg-input);color:var(--fg-2); }
.nt-ed-save{ border:0;background:var(--accent);color:var(--accent-fg); }
/* B63 W9 (149) — the Application / Domain / Sub-domain editor panel body
   (openDomainEditor). Reuses .nt-editor/.nt-ed-f for the fields; these four
   are new: a two-column row, a small section label, the "inherited /
   overridden" note under a colour pair, and the staging-only callout. */
.nt-editor .grid2{ display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px; }
.nt-editor .sect-t{ font:700 10.5px var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3); }
.nt-editor .inherit{ font:500 11px var(--mk-font-ui);color:var(--fg-3);margin:2px 0 12px; }
.nt-editor .note{ border-radius:10px;background:color-mix(in srgb,var(--mk-ok,#1f9d57) 10%,transparent);border:1px solid color-mix(in srgb,var(--mk-ok,#1f9d57) 30%,transparent);color:var(--fg-2);font:500 11.5px/1.45 var(--mk-font-ui);padding:9px 11px;margin:4px 0 12px; }
.nt-ed-color{ height:36px;padding:2px;border-radius:8px;border:1px solid var(--border);background:var(--bg-2);cursor:pointer; }
.nt-ed-locked{ color:var(--fg-3);display:flex;align-items:center;height:36px; }
/* routes tab header */
.rt-head{ padding:2px 0 14px; }
.rt-head-t{ display:flex;flex-direction:column;gap:2px; }
.rt-head-t b{ font:700 15px var(--mk-font-ui);color:var(--fg-1); }
.rt-head-t span{ font:500 12.5px var(--mk-font-ui);color:var(--fg-3);text-wrap:pretty; }
/* B58 wave 3 — the routes ledger: what the references owe, in the same two
   severities the design-system gate uses (hard = a reference that cannot
   resolve and blocks a deploy; soft = a declaration still owed). */
.rt-lg{ border:1px solid var(--border);border-radius:12px;padding:11px 13px;margin:0 0 14px;background:var(--bg-2); }
.rt-lg.is-ok{ display:flex;align-items:center;gap:8px;flex-wrap:wrap;font:600 12px/1.4 var(--mk-font-ui);color:var(--fg-2); }
.rt-lg.is-ok .mi{ font-size:17px;color:var(--mk-ok); }
.rt-lg.is-ok .rt-lg-s{ font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-3);flex:1 1 220px;min-width:0; }
.rt-lg.is-bad{ border-color:color-mix(in srgb,var(--mk-danger) 55%,transparent);background:color-mix(in srgb,var(--mk-danger) 8%,var(--bg-1)); }
.rt-lg.is-warn{ border-color:color-mix(in srgb,var(--mk-warning) 55%,transparent);background:color-mix(in srgb,var(--mk-warning) 9%,var(--bg-1)); }
.rt-lg-h{ display:flex;align-items:center;gap:7px;font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.rt-lg-h .mi{ font-size:17px; }
.rt-lg.is-bad .rt-lg-h .mi{ color:var(--mk-danger); }
.rt-lg.is-warn .rt-lg-h .mi{ color:var(--mk-warning); }
.rt-lg-c{ margin-inline-start:auto;font:700 11px/1.6 var(--mk-font-mono);color:var(--fg-3); }
.rt-lg-s{ margin:5px 0 8px;font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-3);text-wrap:pretty; }
.rt-lg-l{ display:flex;flex-wrap:wrap;gap:5px; }
.rt-lg-i{ display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:3px 9px;border-radius:999px;
  background:var(--bg-1);border:1px solid var(--border);font:600 10.5px/1.6 var(--mk-font-ui);color:var(--fg-2);
  cursor:pointer;text-align:start; }
.rt-lg-i:hover{ border-color:var(--accent);color:var(--fg-1); }
.rt-lg-i.is-hard{ border-color:color-mix(in srgb,var(--mk-danger) 45%,transparent);color:var(--mk-danger); }
.rt-lg-at{ font:600 10px/1.6 var(--mk-font-mono);color:var(--fg-3);flex:0 0 auto; }
.rt-lg-i.is-hard .rt-lg-at{ color:color-mix(in srgb,var(--mk-danger) 70%,var(--fg-3)); }
/* an unresolved reference, where it is read and where it is edited */
.rt-sum-bind.is-bad .rt-sum-bv{ color:var(--mk-danger); }
.rt-sum-bx{ font-size:14px;color:var(--mk-danger); }
.rt-bind-row.is-bad{ box-shadow:inset 2px 0 0 var(--mk-danger); }
/* arriving from a gap chip: the row that owes the fix says so for a moment */
.rt-data-row.rt-focus,.rt-bind-row.rt-focus,.rt-comp-row.rt-focus{ outline:2px solid var(--accent);outline-offset:2px;border-radius:8px;
  animation:rtFocusPulse 2.2s ease-out 1; }
@keyframes rtFocusPulse{ 0%{background:color-mix(in srgb,var(--accent) 22%,transparent)} 100%{background:transparent} }
/* how much of a component this route feeds: k of m context fields */
.rt-sum-fed,.rt-comp-fed{ margin-inline-start:6px;padding:1px 6px;border-radius:999px;border:1px solid var(--border);
  font:700 9.5px/1.5 var(--mk-font-mono);color:var(--fg-3);background:var(--bg-1);flex:0 0 auto; }
.rt-comp-fed{ margin-inline-start:2px; }
.rt-sum-fed.is-owed,.rt-comp-fed.is-owed{ color:var(--mk-danger);border-color:color-mix(in srgb,var(--mk-danger) 45%,transparent); }



/* ═══ B31 — Backend tree & entity field form ═══════════════════════ */
/* C9 — containers (apps / services / entities / collection params) wear the
   blue/accent shading; DEAD-END leaf fields are the gray ones. */
/* C9 — containers (apps / services / entities / collection params) wear the
   blue/accent shading; DEAD-END leaf fields are the gray ones.
   C27 (Pablo B34): the tint lives on the ICON background, NOT the whole box —
   the box stays neutral (only a faint accent border marks a container). */
.be-tree .nt-kind-app > .nt-box,
.be-tree .nt-kind-service > .nt-box,
.be-tree .nt-kind-entity > .nt-box,
.be-tree .nt-kind-param:not(.nt-leaf) > .nt-box {
  border-color: color-mix(in srgb, var(--accent) 20%, var(--border));
}
.be-tree .nt-kind-app > .nt-box .nt-ic:not(.nt-ic-img),
.be-tree .nt-kind-service > .nt-box .nt-ic:not(.nt-ic-img),
.be-tree .nt-kind-entity > .nt-box .nt-ic:not(.nt-ic-img),
.be-tree .nt-kind-param:not(.nt-leaf) > .nt-box .nt-ic:not(.nt-ic-img) {
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
/* B52-04 (Pablo: "Why do we have some entities showing up grayed out? This
   shouldn't be the case") — ROOT CAUSE: `nt-leaf` is set on any node with
   `target` and no children, and an ENTITY only grows children for its
   multi-select / collection / multi-relation fields (B35 S11a). So every entity
   without one — Currency, Country, Ticket, Service — collected the leaf's gray
   `--bg-2` fill and dimmed `--fg-2` label and read as disabled. The dimming is
   meant for the END of a field chain, so it is scoped to params: an entity is a
   first-class object whether or not it happens to hold a collection. */
.be-tree .nt-node.nt-leaf.nt-kind-param > .nt-box { background: var(--bg-2); }
.be-tree .nt-node.nt-leaf.nt-kind-param > .nt-box .nt-ic,
.be-tree .nt-node.nt-leaf.nt-kind-param > .nt-box .nt-label { color: var(--fg-2); }
/* C14 — application logos. B32 C1: the logo sits on a soft neutral TILE with
   padding, CONTAINED (not cropped), and swaps its light/dark variant with the
   theme (img.nt-img-l = light-theme art, img.nt-img-d = dark-theme art). */
.nt-ic-img{
  width:24px;height:24px;border-radius:6px;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--bg-2);border:1px solid var(--border);
  overflow:hidden;
}
.nt-ic-img img{width:16px;height:16px;object-fit:contain;display:block}
.nt-ic-img.round{border-radius:50%}
.nt-ic-img.round img{width:100%;height:100%;object-fit:cover;border-radius:50%}
html[data-theme="dark"] .nt-ic-img .nt-img-l{display:none}
html[data-theme="light"] .nt-ic-img .nt-img-d{display:none}
html:not([data-theme="dark"]) .nt-ic-img .nt-img-d{display:none}

/* ── B32 C16 — rich route editor ─────────────────────────────────────── */
/* B34 C14 — the route editor lives in a slide-in PANEL (summary + Edit flip)
   rather than an inline box. The panel reuses .filter-panel/.ent-panel chrome. */
.route-edit-panel .rt-editor.rt-editor-panel{border:0;background:transparent;padding:0;gap:12px}
/* B61 - this IS the app's view-only form grammar. Pablo asked the wallet panel to
   reuse it ("We have a form and view-only form layout in several places of the
   prototype already please try to re-use components"), so the SAME rules now answer
   to a neutral name as well: one definition, two selectors. New surfaces should use
   .vf/.vf-row/.vf-l/.vf-v; .rt-sum* stays for the route summary that coined it. */
.rt-sum,.vf{display:flex;flex-direction:column;gap:0}
.rt-sum-row,.vf-row{display:flex;flex-direction:column;gap:6px;padding:12px 0;border-bottom:1px solid var(--divider,var(--border))}
.rt-sum-l,.vf-l{display:flex;align-items:center;gap:7px;font:700 11px var(--mk-font-ui);color:var(--fg-3);letter-spacing:.03em;text-transform:none}
.rt-sum-l .mi,.vf-l .mi{font-size:16px;color:var(--accent-text)}
.rt-sum-v,.vf-v{font:600 13px var(--mk-font-ui);color:var(--fg-1);min-width:0}
.vf-v{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.rt-sum-path{display:inline-block;padding:4px 9px;border-radius:7px;background:var(--bg-2);font:600 12.5px var(--mk-font-mono, ui-monospace, monospace);color:var(--fg-1);word-break:break-all}
.rt-sum-ds{font-weight:600}
.rt-sum-chips{display:flex;flex-wrap:wrap;gap:6px}
.rt-sum-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;background:var(--bg-2);border:1px solid var(--border);font:600 11.5px var(--mk-font-ui);color:var(--fg-1)}
.rt-sum-chip .mi{font-size:14px;color:var(--accent-text)}
.rt-sum-chip.rt-sum-call{background:color-mix(in srgb, var(--accent) 8%, var(--bg-1));border-color:transparent;color:var(--accent-text)}
.rt-sum-empty{font:500 12px var(--mk-font-ui);color:var(--fg-3)}
/* B57-H step 5/6 — the summary READS the route back: a data extraction as
   "name from Entity › field", a component with its bindings underneath as
   "prop ← source · value", and the render-time story stated once at the end. */
.rt-sum-data b{font-weight:700}
.rt-sum-from{color:var(--fg-3);font-weight:500}
.rt-sum-undec{font-style:italic;color:var(--warn-text,var(--fg-3))}
.rt-sum-comps{display:flex;flex-direction:column;gap:8px}
.rt-sum-comp{display:flex;flex-direction:column;gap:5px;align-items:flex-start}
.rt-sum-binds{display:flex;flex-direction:column;gap:3px;padding-inline-start:10px;border-inline-start:2px solid var(--border);margin-inline-start:6px}
.rt-sum-bind{display:flex;align-items:center;gap:6px;font:600 11.5px var(--mk-font-ui);min-width:0}
.rt-sum-bk{color:var(--fg-2)}
.rt-sum-ba{color:var(--fg-3)}
html[dir="rtl"] .rt-sum-ba{transform:scaleX(-1)}
.rt-sum-bv{color:var(--accent-text);font-family:var(--mk-font-mono, ui-monospace, monospace);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rt-sum-note{display:flex;gap:9px;margin-top:14px;padding:11px 12px;border-radius:10px;background:var(--bg-2)}
.rt-sum-note .mi{font-size:17px;color:var(--accent-text);flex:0 0 auto}
.rt-sum-note p{margin:0;font:500 12px/1.55 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty}
.rt-sum-edit{display:inline-flex;align-items:center;justify-content:center;gap:7px;margin-top:16px;padding:11px 16px;border:0;border-radius:10px;background:var(--accent);color:var(--accent-fg,#04282b);cursor:pointer;font:700 13px var(--mk-font-ui);align-self:flex-start}
.rt-sum-edit:hover{filter:brightness(1.05)}
.rt-sum-edit .mi{font-size:17px}
.rt-hd-acts{display:flex;align-items:center;gap:4px}
.rt-hd-edit .mi{color:var(--accent)}
.rt-editor{display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid var(--border);border-radius:10px;background:var(--bg-1)}
.rt-ed-grid{display:flex;gap:10px;flex-wrap:wrap}
.rt-ed-grid .nt-ed-f{flex:1 1 140px;min-width:0}
.rt-ed-langs .nt-ed-f{flex:1 1 120px}
.rt-ed-sec{font:700 11px var(--mk-font-ui);color:var(--fg-3);letter-spacing:.04em;margin-top:2px}
.rt-ed-path{display:flex;align-items:center;height:34px;padding:0 10px;border-radius:8px;background:var(--bg-2);font:600 12px var(--mk-font-mono, ui-monospace, monospace);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rt-ds-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.rt-ds-chip{display:inline-flex;align-items:center;gap:5px;padding:5px 9px;border-radius:999px;background:var(--bg-2);border:1px solid var(--border);font:600 12px var(--mk-font-ui);color:var(--fg-1)}
.rt-ds-chip .mi{font-size:14px;color:var(--accent-text)}
.rt-ds-chip.is-last{background:var(--accent-soft);border-color:transparent;color:var(--accent-text)}
.rt-ds-x{border:0;background:transparent;cursor:pointer;display:inline-flex;padding:0;color:inherit}
.rt-ds-x .mi{font-size:14px}
.rt-ds-sep{font-size:14px;color:var(--fg-3)}
html[dir="rtl"] .rt-ds-sep{transform:scaleX(-1)}
.rt-ds-sel{max-width:220px;height:32px;font-size:12px}
/* B57-H step 5 — a route's data is a LIST of named extractions, so each one is a
   row with its own name, list/one posture, drill chain and filter. `is-unset` is
   the honest state: a name the bindings reference whose source was never declared. */
.rt-data-row{border:1px solid var(--border);border-radius:9px;background:color-mix(in srgb, var(--accent) 4%, var(--bg-1));padding:8px 9px;margin-bottom:6px;display:flex;flex-direction:column;gap:7px}
.rt-data-row.is-unset{border-style:dashed;background:var(--bg-1)}
.rt-data-hd{display:flex;align-items:center;gap:7px}
.rt-data-ic{font-size:16px;color:var(--accent-text)}
.rt-data-nm{flex:1 1 90px;min-width:0;height:32px;font-size:12px;font-weight:600}
.rt-data-many{flex:0 0 auto}
.rt-data-filt{margin:0}
.rt-data-filt>span{font:700 10.5px var(--mk-font-ui);color:var(--fg-3)}
.rt-data-filt .ent-input{height:30px;font-size:12px}
.rt-bind-path{flex:0 1 92px;min-width:0;height:32px;font-size:12px}
.rt-param-row{display:flex;gap:6px;align-items:center;margin-bottom:6px}
.rt-param-nm{flex:1.2 1 90px;min-width:0;height:32px;font-size:12px}
.rt-param-t,.rt-param-s{flex:1 1 84px;min-width:0;height:32px;font-size:12px}
.rt-param-x{flex:0 0 auto}
.rt-ed-add{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;border:1px dashed var(--border);background:transparent;border-radius:8px;padding:6px 11px;cursor:pointer;font:600 12px var(--mk-font-ui);color:var(--fg-2)}
.rt-ed-add:hover{color:var(--accent);border-color:var(--accent)}
.rt-ed-add .mi{font-size:15px}
.rt-ed-empty{font:500 12px var(--mk-font-ui);color:var(--fg-3);padding:4px 2px}
.rt-comp-row{border:1px solid var(--border);border-radius:9px;background:color-mix(in srgb, var(--accent) 4%, var(--bg-1));margin-bottom:6px;overflow:hidden}
.rt-comp-main{display:flex;align-items:center;gap:8px;padding:7px 9px}
.rt-comp-ic{font-size:16px;color:var(--accent-text)}
.rt-comp-nm{font:600 12.5px var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.rt-call-tag{display:inline-flex;align-items:center;gap:3px;padding:2px 7px;border-radius:999px;background:var(--accent-soft);color:var(--accent-text);font:700 10px var(--mk-font-ui)}
.rt-call-tag .mi{font-size:12px}
.rt-comp-acts{display:flex;gap:2px;margin-inline-start:auto}
.rt-comp-binds{border-top:1px solid var(--border);padding:8px 9px;display:flex;flex-direction:column;gap:6px;background:var(--bg-1)}
.rt-bind-row{display:flex;align-items:center;gap:6px}
.rt-bind-l{flex:1 1 80px;min-width:0;font:600 12px var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rt-bind-src{flex:0 0 118px;height:30px;font-size:11.5px}
.rt-bind-v{flex:1 1 90px;min-width:0;height:30px;font-size:11.5px}
.rt-ed-addcomp .rt-ds-sel{width:100%;max-width:none}

/* ── B32 C11 (= B31 C26) — the tab strip INSIDE the scroll surface, sticky
      under the page header, wearing the header's glass band. sections.js
      moves .sec-tabs into .page (after .page-h) on desktop/tablet and sets
      its sticky `top` to the measured header height. ── */
.page > .sec-tabs.sec-tabs-inpage{
  position:sticky;z-index:19;
  padding:0 24px;
  /* C2 (Pablo) — .page is a flex column with an 18px row-gap, which opened an
     18px gutter between the header and this in-page tab strip. Cancel just that
     top gap so the tabs sit FLUSH under the header (the gap below the tabs, to
     the content, is kept). C1 — flush + sticky top:=headerHeight (set inline by
     syncTabsBelowHeader) keeps the strip pinned right under the sticky header. */
  margin:-18px 0 0;
  background:transparent;
}
/* ── B60 — the strip's GLASS now lives in shell.css, in one rule shared with
      `.page-h`, because Pablo asked for the two to be the same thing rather than two
      near-copies ("it looks a bit different than the header (when it really
      shouldn't) and the blur is applied to a whole area"). Everything that used to
      be here — the transparent-at-rest ::before, the `body.scrolled` / `.is-under`
      wash with its -26px overhang, and the 64px trailing ::after — is retired.
      Do NOT re-add a copy here: the whole point is that there is one definition.
      `.is-under` is still set by syncTabsBelowHeader (harmless, and it is what the
      JS side reads); it just no longer switches a paint. */
/* B44 C31 (Pablo) — the blur belongs to the BACKGROUND layer (::before,
   z-index:-1), so the content scrolling behind is softened; the tab icon +
   label must stay crisp. Force the tab items above the blur layer.
   B58 — `isolation:isolate` USED to be on the strip here, and it was the reason
   the band never actually blurred anything: an isolated element is its own
   BACKDROP ROOT, so `backdrop-filter` on a descendant has nothing behind it to
   sample. It was also redundant — `position:sticky` + `z-index:19` already make
   this a stacking context, which is what keeps the z-index:-1 pseudos behind the
   tabs but above the scrolling page. */
.page > .sec-tabs.sec-tabs-inpage > *{ position:relative;z-index:1;backdrop-filter:none;-webkit-backdrop-filter:none;filter:none; }

/* ── B31 C27 — route-driven Create (header pill + mobile FAB) ────────── */
.route-create{ position:relative;display:inline-flex; }
.nav-pill.route-create-btn{
  background:var(--accent);border-color:var(--accent);color:var(--accent-fg,#04282b);
  font-weight:700;
}
.nav-pill.route-create-btn:hover{ filter:brightness(1.06); }
/* C3 — the "+" glyph must stay white on the accent fill (accent-fg can be dark). */
.nav-pill.route-create-btn .mi{ color:#fff; }
/* C20 / C3 — entity collection rows span the full panel width. The row was
   display:block, so the inner button's flex:1 did nothing and it shrank to its
   content (~190px). Make the row a flex container so the main button fills it
   (the acts cluster is absolutely positioned, so it doesn't affect the flow). */
.ent-panel .cmp-ctx-row.ent-row{ width:100%;display:flex;align-items:center; }
.ent-panel .cmp-ctx-row.ent-row .cmp-ctx-main{ flex:1 1 auto;min-width:0;width:100%; }
.route-create-menu{
  position:absolute;top:calc(100% + 8px);inset-inline-end:0;z-index:900;
  min-width:210px;display:none;flex-direction:column;padding:6px;
  background:var(--bg-1);border:1px solid var(--border);border-radius:12px;
  box-shadow:0 14px 34px rgba(13,37,48,.18);
}
.route-create-menu.open{ display:flex; }
.route-create-item{
  display:flex;align-items:center;gap:9px;padding:9px 11px;border:0;border-radius:8px;
  background:transparent;cursor:pointer;font:600 13px var(--mk-font-ui);color:var(--fg-1);
  text-align:start;
}
.route-create-item:hover{ background:var(--bg-2);color:var(--accent-text); }
.route-create-item .mi{ font-size:17px;color:var(--accent-text); }
.route-fab{ position:fixed;inset-inline-end:18px;bottom:calc(76px + env(safe-area-inset-bottom,0px));z-index:880;display:none; }
.route-fab-btn{
  width:52px;height:52px;border-radius:50%;border:0;cursor:pointer;
  background:var(--accent);color:var(--accent-fg,#04282b);
  box-shadow:0 10px 26px rgba(13,37,48,.28);
  display:inline-flex;align-items:center;justify-content:center;
  transition:transform .18s var(--mk-ease);
}
.route-fab-btn .mi{ font-size:26px;transition:transform .18s var(--mk-ease); }
.route-fab.open .route-fab-btn .mi{ transform:rotate(45deg); }
.route-fab .route-create-menu{ top:auto;bottom:calc(100% + 10px); }
/* desktop/tablet → header pill; mobile (portrait AND landscape) → FAB (C6) */
@media (min-width:601px) and (min-height:600px){ .route-fab{ display:none !important; } }
@media (max-width:600px){
  #routeCreateWrap{ display:none !important; }
  .route-fab{ display:block; }
}
/* B39 C6 — mobile-landscape (short viewport) also floats the FAB instead of
   the navbar pill, matching portrait. */
@media (max-height:599px) and (orientation:landscape){
  #routeCreateWrap{ display:none !important; }
  .route-fab{ display:block; }
}
/* ── B58 — where the FAB actually sits, per configuration (Pablo, four comments
      in one batch). Portrait WITH tabs is the approved reference ("this
      configuration is ok") and keeps the 76px lift that clears the bottom tab
      bar. The other three configurations were wrong:
        · portrait with NO tabs → nothing to clear, so it drops to the corner
          ("the floating button can be further down in the screen"),
        · landscape → the tab strip is a 64px RAIL on the trailing edge, so the
          FAB was sitting on top of it ("needs to be further to the center") and
          it hung too high ("can go further down"),
        · over a panel → it should not be there at all.
      `#shell.has-page-tabs` is the one honest signal for "this route has tabs";
      the FAB is a sibling of #shell (body child), hence the `~`. */
@media (max-width:600px) and (orientation:portrait){
  .route-fab{ bottom:calc(18px + env(safe-area-inset-bottom,0px)); }
  #shell.has-page-tabs ~ .route-fab{ bottom:calc(76px + env(safe-area-inset-bottom,0px)); }
}
@media (max-height:599px) and (orientation:landscape){
  .route-fab{ bottom:calc(14px + env(safe-area-inset-bottom,0px)); }
  #shell.has-page-tabs ~ .route-fab{ inset-inline-end:calc(64px + 16px); }
}
/* B67 R67-003 — wherever the floating + shows (phone portrait + landscape), the end of every page clears it: at the end of
   the scroll the last row's own controls sat under it (Places "Country house" + / ⋯, a Gantt card's priority and assignee,
   a Backlog row's assignee, Drive's rename, Support / Catalog / Stock "+"). The FAB is 52 px + 14–18 px off the edge. */
@media (max-width:600px), (max-height:599px) and (orientation:landscape){
  .page-view:not(.wk-open):not(.fc-open) > .page:not(:has(> .mx))::after{ content:'';display:block;flex:0 0 auto;height:72px;pointer-events:none; }   /* Map scrolls its own list (padded below) */
  .page-view .mx-list{ padding-bottom:76px; }
  .gantt-wrap{ padding-bottom:84px; }
  /* B67 R23 (R67-094) — the spine editor (Frontend / Assets, in the main slide) runs past the slide's box, so the page's end
     spacer sat above its real end: the inspector's "+ Domain" ended under the +. Its own end clears it. */
  .mc-slide .sp-ed{ padding-bottom:100px; }
}
/* A floating create button never sits on top of a panel, a modal or a sheet —
   the same discipline (and the same `:has()` signal) as the Play entry.
   B62 § M-88 ("the moment any panel opens, the FAB is gone") — keyed on the GENERIC
   `.panel-scrim.open` as well: #panelScrim is only the ROUTE panel's scrim, so the
   wallet / trip / game panel (`.panel-scrim.wallet-scrim`), the node view, the icon
   panel and the chat composer all floated the create button over themselves on a
   phone. Measured: display=block with the trip panel open at 390×844. */
/* ═══ B62 § S-16 · WORKSHOP ▸ FLOWCHARTS ═══════════════════════════
   Pablo: "Flowcharts (helps me create flowcharts, similar to the workflow
   creation on the entity form)" — so the EDITOR has no CSS here at all: it is
   `workflow-diagram.css`, unchanged. What is new is only the list: a card whose
   thumbnail is the chart through the engine's own painter, the reading, and the
   panel that states what the chart says and what is missing from it. */
.fc-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px }
.fc-card{ display:flex;flex-direction:column;border:1px solid var(--bd-1);border-radius:14px;
  background:var(--bg-1);overflow:hidden;cursor:pointer;min-width:0;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast),transform var(--mk-t-fast) }
.fc-card:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--bd-1));box-shadow:var(--shadow-sm);transform:translateY(-1px) }
.fc-card:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
/* The miniature is laid out at the chart's real size and scaled by fcFit() from
   the card's MEASURED width — a hard-coded scale renders every chart into a
   corner of its card (the defect Canvas's thumbnails paid for). */
.fc-thumb{ position:relative;display:block;aspect-ratio:16/9;overflow:hidden;
  background:var(--bg-2);border-bottom:1px solid var(--bd-1) }
.fc-thumb-in{ position:absolute;left:0;top:0;display:block;transform-origin:0 0;direction:ltr }
/* A preview is not interactive: the engine's hover, cursor and focus affordances
   would promise an edit the card does not offer (the card opens the panel). */
.fc-thumb .wf-canvas.is-preview{ position:relative;background:transparent;border:0 }
.fc-thumb .wf-node{ pointer-events:none;cursor:default }
.fc-thumb .wf-bend,.fc-thumb .wf-endh,.fc-thumb .wf-edge-hit{ display:none }
/* A THUMBNAIL SHOWS THE SILHOUETTE, NOT THE WORDS. A 1300px chart in a 330px
   card is a 0.25 scale, so a 13px step name measures THREE PIXELS — it rendered
   as grey smudges that read as damage rather than as text. The card's words are
   its title, its subtitle and its reading, all at full size; the thumbnail's job
   is "which chart is this", answered by shape and colour.
   AND EVERY LINE WEIGHT HAS TO BE RE-CHOSEN AT THAT SCALE — the same lesson the
   canvas handles taught, one screen over. The editor's pill is a 1px border and
   a surface fill one step off its ground: at 0.25 that is a quarter-pixel border
   and an invisible fill, so the pill disappeared and left a bare dot. In the
   preview the TINT becomes the fill (it is the one thing that survives), which
   also makes the dot redundant, and the wires are thickened to stay visible. */
.fc-thumb .wf-node-nm,.fc-thumb .wf-node-def,.fc-thumb .wf-node-end,.fc-thumb .wf-dot{ display:none }
.fc-thumb .wf-node{ border-width:0;border-radius:14px;box-shadow:none;
  background:color-mix(in srgb,var(--wf-tint) 82%,var(--bg-1)) }
.fc-thumb .wf-edge-line{ stroke:var(--fg-3);stroke-width:5px }
.fc-thumb .wf-svg marker path{ fill:var(--fg-3) }
.fc-card-b{ display:flex;flex-direction:column;gap:5px;padding:11px 13px 13px;min-width:0 }
.fc-card-nm{ font:800 14px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap }
.fc-card-sub{ font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden }
.fc-read{ font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.fc-read b{ color:var(--fg-1);font-weight:800 }
.fc-mark{ display:inline-flex;align-items:center;gap:6px;align-self:flex-start;margin-top:2px;
  font:700 11px/1.3 var(--mk-font-ui);border-radius:var(--mk-radius-pill);padding:5px 10px;
  max-width:100%;min-width:0 }
.fc-mark .mi{ font-size:14px;flex:0 0 auto }
.fc-mark i{ font-style:normal;opacity:.7 }
/* The ink on a tint is ordinary TEXT ink — the tint carries the state (the
   accent-on-accent-tint defect this batch paid for five times). */
.fc-mark.is-ok{ color:var(--fg-1);background:var(--bg-2) }
.fc-mark.is-bad{ color:var(--fg-1);background:color-mix(in srgb,var(--mk-danger,#C81E1E) 13%,transparent) }
/* ── the chart's panel ── */
.wl-sumbox.fc-from{ cursor:pointer;min-height:48px }
.wl-sumbox.fc-from:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.fc-go{ flex:0 0 auto;font-size:18px;color:var(--fg-3) }
.fc-nums{ display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:8px 0 4px }
.fc-num{ display:flex;flex-direction:column;align-items:center;gap:2px;padding:9px 6px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1);
  font:600 10.5px/1.25 var(--mk-font-ui);color:var(--fg-2);text-align:center }
.fc-num b{ font:800 19px/1.1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.fc-find{ display:flex;align-items:flex-start;gap:9px;padding:9px 11px;margin-bottom:7px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1) }
.fc-find .mi{ flex:0 0 auto;font-size:18px;color:var(--fg-2);margin-top:1px }
.fc-find.sev-2{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 34%,var(--border));
  background:color-mix(in srgb,var(--mk-danger,#C81E1E) 8%,transparent) }
.fc-find.sev-2 .mi{ color:var(--mk-danger,#C81E1E) }
.fc-find-b{ flex:1;min-width:0;display:flex;flex-direction:column;gap:1px }
.fc-find-t{ font:700 12.5px/1.4 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
.fc-find-s{ font:600 11px/1.35 var(--mk-font-ui);color:var(--fg-2) }
.fc-path{ display:flex;flex-direction:column;gap:0;margin:8px 0 }
.fc-step{ display:flex;align-items:flex-start;gap:10px;padding:9px 11px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1) }
.fc-step-d{ flex:0 0 auto;width:10px;height:10px;border-radius:50%;margin-top:4px }
.fc-step-b{ flex:1;min-width:0;display:flex;flex-direction:column;gap:1px }
.fc-step-t{ font:700 12.5px/1.35 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
html[dir="rtl"] .fc-step-t{ unicode-bidi:plaintext; text-align:right; }   /* B67 R67-038 — "Is every dish available?" read "?Is every dish available" (R67-014) */
.fc-step-k{ font:600 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
.fc-step-a{ align-self:center;font-size:17px;color:var(--fg-3);margin:2px 0 }
.fc-acts{ display:flex;flex-wrap:wrap;gap:7px;margin:14px 0 4px }
/* A filled-accent ground is NOT available for a button here. `--accent-fg` is
   white by Pablo's 2026-06-01 decision (navy ink read "weird"), and white on
   #03C9CB measures 2.48:1 — so the primary action takes the pairing § S-03
   measured instead: the accent TINT as the ground, the accent INK on it
   (4.72:1). `--accent` is the FILL token; `--accent-text` is the ink. Sixth time
   in B62 for that distinction. */
button.wl-chip.is-primary{ background:var(--accent-soft);
  border-color:color-mix(in srgb,var(--accent) 52%,var(--bd-1));color:var(--accent-text);font-weight:800 }
button.wl-chip.is-primary .mi{ color:var(--accent-text) }
/* § M-43 — the same three bands the rest of this batch was corrected for, and
   the same specificity discipline: a raise must out-specify the floor. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  .fc-card{ min-height:44px }
  .fc-acts button.wl-chip{ min-height:44px }
  .fc-find{ min-height:48px }
  /* The engine's own modal controls, raised in this section's bands too — its
     bar buttons and inspector fields are the only road to an edit here. */
  .wf-modal button.wf-btn,.wf-modal button.wf-flag,.wf-modal button.wf-del,
  .wf-modal button.wf-tr,.wf-modal .wf-modal-x{ min-height:44px }
  .wf-modal input.ent-input,.wf-modal select.ent-input{ min-height:44px }
}
@media (max-width:600px){
  .fc-grid{ grid-template-columns:1fr }
  .fc-nums{ grid-template-columns:repeat(2,minmax(0,1fr)) }
}

/* ═══ B62 § S-16 · WORKSHOP ▸ SUITE (Docs / Sheets / Slides) ═══════
   "Suite (will have tabs like: Docs (similar to word), Sheets (similar to
   excel), Slides (similar to powerpoint). All of these items would be live
   edited."
   ONE RULE GOVERNS THE WHOLE SECTION: a bound value LOOKS bound, in all three
   surfaces, with the same chip — so a reader can tell which words are the app's
   and which are the author's without being told. Everything else here is the
   three kinds earning their tabs: prose, a grid, a surface read across a room. */
.su-grid-cards{ display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:14px }
.su-card{ display:flex;flex-direction:column;border:1px solid var(--bd-1);border-radius:14px;
  background:var(--bg-1);overflow:hidden;cursor:pointer;min-width:0;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast),transform var(--mk-t-fast) }
.su-card:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--bd-1));box-shadow:var(--shadow-sm);transform:translateY(-1px) }
.su-card:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.su-card-b{ display:flex;flex-direction:column;gap:5px;padding:11px 13px 13px;min-width:0 }
.su-card-nm{ font:800 14px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.su-card-s{ font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden }
.su-card-m{ font:600 10.5px/1.3 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums }
.su-mark{ display:inline-flex;align-items:center;gap:5px;align-self:flex-start;
  font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-2);background:var(--bg-2);
  border-radius:var(--mk-radius-pill);padding:5px 9px }
.su-mark .mi{ font-size:13px }
.su-mark.is-live{ color:var(--fg-1);background:var(--accent-soft) }
.su-mark.is-live .mi{ color:var(--accent-text) }
/* ── the card previews: the real surface, small, so the card cannot lie ── */
.su-pv{ display:block;aspect-ratio:16/10;overflow:hidden;padding:12px 13px;
  background:var(--bg-2);border-bottom:1px solid var(--bd-1);position:relative }
.su-pv-doc{ display:flex;flex-direction:column;gap:4px }
.su-pv-l{ display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:500 8.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
.su-pv-h1{ font:800 12px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.su-pv-h2{ font:800 9.5px/1.2 var(--mk-font-ui);color:var(--fg-1);margin-top:2px }
.su-pv-note{ color:var(--fg-3);font-style:italic }
.su-pv-sheet{ display:flex;flex-direction:column;gap:2px }
.su-pv-row{ display:grid;grid-template-columns:repeat(4,1fr);gap:2px }
.su-pv-c{ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:2px 3px;border-radius:2px;
  background:var(--bg-1);font:500 7.5px/1.4 var(--mk-font-ui);color:var(--fg-2) }
.su-pv-c.is-b{ font-weight:800;color:var(--fg-1);background:var(--bg-0) }
.su-pv-c.is-live{ background:var(--accent-soft);color:var(--fg-1);font-weight:700 }
.su-pv-slides{ display:flex;align-items:center;justify-content:center }
.su-pv-sl{ display:flex;flex-direction:column;gap:5px;width:78%;padding:12px 14px;border-radius:8px;
  background:var(--bg-1);border:1px solid var(--bd-1) }
.su-pv-sl b{ font:800 11px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap }
.su-pv-sl i{ font:500 8px/1.35 var(--mk-font-ui);color:var(--fg-2);font-style:normal;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.su-pv-count{ position:absolute;top:8px;inset-inline-end:10px;font:800 9.5px/1 var(--mk-font-ui);
  color:var(--fg-2);background:var(--bg-1);border-radius:var(--mk-radius-pill);padding:4px 8px }
/* ── ★ ONE CHIP FOR A BOUND VALUE, in every surface ──────────────────
   THE TINT CARRIES "THIS IS LIVE"; THE INK IS ORDINARY TEXT. Every accent-ink
   pairing this batch measured (4.63:1, 4.72:1) was accent ink on the PAGE
   ground — on its own 15% tint the same ink is 3.9:1 in light and 3.59:1 in
   dark, because the tint is the thing it has to be read against. That is the
   identical trap the red and green chips below fell into, so all three take the
   same answer: `--fg-1`, which is legible on every ground in both themes by
   construction rather than by a hand-picked hex per state. The bolt glyph and
   the tint already say "live" — the ink does not have to. */
.su-live{ display:inline-flex;align-items:baseline;gap:3px;padding:1px 6px;border-radius:6px;
  background:var(--accent-soft);color:var(--fg-1);font-weight:800;
  font-variant-numeric:tabular-nums;white-space:nowrap }
.su-live-b{ font-size:12px;align-self:center;color:var(--accent-text);opacity:.9 }
/* THE TINT CARRIES THE STATE AND THE INK IS ORDINARY TEXT — the app's own rule,
   and the chip is why it exists. `--mk-danger` #C81E1E is 5.42:1 on white but
   only 3.77:1 on its OWN 14% tint, because the tint is the thing it has to be
   read against. Measured: 3.77 → 8.9 in light, and the pairing works in the dark
   theme for free, which a hand-picked deep red would not. */
.su-live.is-ok{ background:color-mix(in srgb,var(--mk-ok,#157F4C) 15%,transparent);color:var(--fg-1) }
.su-live.is-warn{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 15%,transparent);color:var(--fg-1) }
.su-live.is-gone{ background:var(--bg-2);color:var(--fg-2);font-style:italic }
.su-empty{ color:var(--fg-4);font-style:italic }
/* ── the open document's bar (it replaces the page header, as Canvas's does) ── */
.page-view.su-open .page-h{ display:none }
/* B63-105 — "when I'm opening a file on the suite, the tabs shouldn't show
   up. Only the option to go back…": `.page-h` was already hidden, but the
   Docs/Sheets/Slides `.sec-tabs` strip (moved into `.page` by
   `syncTabsBelowHeader` on desktop/tablet) kept showing above the open
   document. The bar (`su-bar`) already carries Back — the tabs would just be
   a second, contradictory way to navigate away. */
.page-view.su-open .sec-tabs{ display:none }
.su-bar{ display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:12px;padding-top:8px }
/* B65 W10 (065-125) — the live-values mark sits on the bar's centre line, like its neighbours */
.su-bar .su-mark{ align-self:center;height:28px;padding:0 11px;font-size:11.5px }
.su-bar-sp{ flex:1;min-width:0 }
.su-bar-nm{ display:inline-flex;align-items:center;gap:7px;padding:6px 10px;border-radius:10px;cursor:pointer;
  font:800 14.5px/1.2 var(--mk-font-ui);color:var(--fg-1);max-width:min(44vw,460px);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.su-bar-nm:hover{ background:var(--bg-2) }
.su-bar-nm:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.su-bar-nm > .mi{ font-size:18px;color:var(--fg-2);flex:0 0 auto }
.su-bar-e{ font-size:15px !important;color:var(--fg-3) }
/* B63-104 — the inline rename input `wlInlineRenameStart` swaps in for the
   bar's name (Suite, Flowcharts): same type scale as `.su-bar-nm`/`.wk-bar-nm`
   so the swap doesn't jump the layout. */
.wl-inline-ren-in{ font:800 14.5px/1.2 var(--mk-font-ui);color:var(--fg-1);
  padding:6px 10px;border-radius:10px;border:1px solid var(--accent);background:var(--bg-1);
  max-width:min(44vw,460px);min-width:120px }
/* ── DOCS: a flowing document, measured for reading not for a dashboard ── */
.su-doc{ max-width:74ch;margin:0 auto;padding:4px 2px 24px }
.su-b{ margin:0 0 12px;cursor:pointer;border-radius:8px;padding:3px 6px;margin-inline:-6px;
  transition:background var(--mk-t-fast) }
.su-b:hover{ background:var(--bg-2) }
.su-b:focus-visible{ outline:2px solid var(--accent);outline-offset:1px }
.su-b.is-sel{ background:var(--accent-soft) }
.su-b-h1{ font:800 26px/1.25 var(--mk-font-ui);color:var(--fg-1);margin-bottom:14px;text-wrap:pretty }
.su-b-h2{ font:800 17px/1.3 var(--mk-font-ui);color:var(--fg-1);margin:22px 0 8px;text-wrap:pretty }
.su-b-p{ font:400 15px/1.7 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
.su-ul{ margin:0 0 12px;padding-inline-start:22px;display:flex;flex-direction:column;gap:2px }
.su-b-ul{ font:400 15px/1.65 var(--mk-font-ui);color:var(--fg-1);margin:0;text-wrap:pretty;list-style:disc }
/* A CALLOUT IS CONTENT, NOT CHROME, so its ink is `--fg-1`. It was the quiet
   tone, which measured 2.05:1 in the dark theme — and this is a box whose whole
   job is to state a rule (CLAUDE.md: text that states a RULE does not take the
   quiet tone). Seventh time in B62 that a tone chosen for chrome was used on
   something a person has to read. */
.su-b-note{ display:flex;gap:10px;padding:11px 13px;border-radius:12px;background:var(--bg-2);
  border:1px solid var(--border);font:500 13.5px/1.6 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
.su-b-note > .mi{ flex:0 0 auto;font-size:18px;color:var(--fg-3);margin-top:1px }
/* ── SHEETS: a real table, because a grid IS one ── */
.su-grid-wrap{ overflow:auto;border:1px solid var(--bd-1);border-radius:12px;background:var(--bg-1);
  -webkit-overflow-scrolling:touch;max-width:100% }
table.su-grid{ border-collapse:separate;border-spacing:0;width:100%;min-width:520px }
.su-gh{ position:sticky;top:0;z-index:2;background:var(--bg-2);color:var(--fg-2);
  font:800 10.5px/1 var(--mk-font-ui);letter-spacing:.05em;text-align:center;padding:8px 6px;
  border-bottom:1px solid var(--border);border-inline-end:1px solid var(--divider) }
.su-gh-r{ position:sticky;inset-inline-start:0;z-index:1;top:auto;min-width:34px }
.su-gh-c{ inset-inline-start:0;z-index:3;min-width:34px }
.su-c{ padding:0;height:40px;border-bottom:1px solid var(--divider);border-inline-end:1px solid var(--divider);
  cursor:pointer;position:relative;vertical-align:middle;background:var(--bg-1) }
.su-c:hover{ background:var(--bg-2) }
.su-c:focus-visible{ outline:2px solid var(--accent);outline-offset:-2px }
.su-c.is-sel{ box-shadow:inset 0 0 0 2px var(--accent) }
.su-c-t{ display:block;padding:0 9px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:500 12.5px/1.3 var(--mk-font-ui);color:var(--fg-1);max-width:240px }
.su-c.is-b .su-c-t{ font-weight:800 }
.su-c.is-b{ background:var(--bg-2) }
.su-c.is-n .su-c-t{ text-align:end;font-variant-numeric:tabular-nums }
.su-c.is-live{ background:var(--accent-soft) }
.su-c.is-live .su-c-t{ color:var(--fg-1);font-weight:800 }
/* A FORMULA cell is marked differently from a bound one, because they are not
   the same claim: one reads a record, the other reads this sheet. */
.su-c.is-f::after{ content:'';position:absolute;top:3px;inset-inline-end:3px;width:0;height:0;
  border-top:6px solid var(--fg-3);border-inline-start:6px solid transparent }
.su-c.is-warn .su-c-t{ color:var(--mk-danger,#C81E1E) }
.su-c.is-ok .su-c-t{ color:var(--mk-ok,#157F4C) }
.su-c.is-warn{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 10%,transparent) }
.su-c.is-ok{ background:color-mix(in srgb,var(--mk-ok,#157F4C) 10%,transparent) }
.su-c-b{ position:absolute;top:2px;inset-inline-start:2px;font-size:11px;color:var(--accent-text);opacity:.8 }
/* ── SLIDES: a surface meant to be read across a room ── */
.su-stage{ display:flex;justify-content:center;padding:2px 0 14px }
.su-slide{ width:100%;max-width:880px;aspect-ratio:16/9;border:1px solid var(--bd-1);border-radius:16px;
  background:var(--bg-1);overflow:hidden;box-shadow:var(--shadow-sm);container-type:inline-size }
.su-sl-in{ height:100%;display:flex;flex-direction:column;gap:14px;padding:6% 7%;justify-content:center }
.su-sl-t{ font:800 clamp(18px,3.6cqi,34px)/1.2 var(--mk-font-ui);color:var(--fg-1);
  text-wrap:pretty;cursor:pointer;border-radius:8px }
.su-sl-t:hover{ background:var(--bg-2) }
.su-sl-t:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.su-sl-title .su-sl-in{ justify-content:center }
.su-sl-bullets .su-sl-in{ justify-content:flex-start }
.su-sl-ul{ margin:0;padding-inline-start:1.1em;display:flex;flex-direction:column;gap:clamp(6px,1.3cqi,14px) }
.su-sl-li{ font:500 clamp(12px,2.1cqi,20px)/1.5 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty;
  cursor:pointer;border-radius:6px }
.su-sl-li:hover{ background:var(--bg-2) }
.su-sl-li:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
/* At this size the INK is allowed to be the signal: headline-scale type needs
   3:1, and --mk-danger on the slide's own surface measures 5.42:1. That is the
   opposite call from the chip above, and the size is the reason. */
.su-sl-num{ font:800 clamp(40px,13cqi,132px)/1 var(--mk-font-ui);color:var(--accent-text);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em }
.su-sl-num.is-ok{ color:var(--mk-ok,#157F4C) }
.su-sl-num.is-warn{ color:var(--mk-danger,#C81E1E) }
/* On a slide the chip would fight type this large, so a bound run keeps the
   value's colour and drops the ground — the marker is the colour itself. */
.su-slide .su-live{ background:transparent;padding:0;gap:2px }
.su-slide .su-live-b{ font-size:.7em }
.su-rail{ display:flex;gap:8px;overflow-x:auto;padding:2px 0 6px;-webkit-overflow-scrolling:touch }
button.su-rail-i{ flex:0 0 auto;display:flex;align-items:center;gap:7px;min-height:40px;max-width:230px;
  padding:7px 11px;border:1px solid var(--bd-1);border-radius:11px;background:var(--bg-1);cursor:pointer;
  font:600 12px/1.25 var(--mk-font-ui);color:var(--fg-1);text-align:start }
button.su-rail-i:hover{ border-color:color-mix(in srgb,var(--accent) 40%,var(--bd-1)) }
button.su-rail-i:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
button.su-rail-i.is-on{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 45%,var(--bd-1));color:var(--fg-1) }
.su-rail-n{ flex:0 0 auto;width:20px;height:20px;border-radius:6px;display:grid;place-items:center;
  background:var(--bg-2);font:800 10.5px/1 var(--mk-font-ui);color:var(--fg-2) }
button.su-rail-i.is-on .su-rail-n{ background:var(--accent);color:var(--accent-fg,#fff) }
.su-rail-t{ min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
/* ── PRESENT: the preview floor (§ M-88), and never a dead end ── */
body.su-presenting{ overflow:hidden }
.su-present{ position:fixed;inset:0;z-index:900;display:flex;flex-direction:column;
  background:var(--bg-0);padding:18px;gap:12px }
.su-present-in{ flex:1;min-height:0;display:flex;align-items:center;justify-content:center }
.su-present-in .su-stage{ width:100%;padding:0 }
.su-present-in .su-slide{ max-width:min(1280px,100%);max-height:100%;border-radius:18px }
.su-present-bar{ flex:0 0 auto;display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap }
.su-present-n{ font:800 13px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums;
  min-width:64px;text-align:center }
/* ── the editors' shared pieces ── */
.su-runs{ display:flex;flex-direction:column;gap:7px;margin:8px 0 }
.su-run{ display:flex;align-items:center;gap:7px }
.su-run-n{ flex:0 0 auto;width:22px;height:22px;border-radius:7px;display:grid;place-items:center;
  background:var(--bg-2);font:800 10.5px/1 var(--mk-font-ui);color:var(--fg-2) }
.su-run.is-live .su-run-n{ background:var(--accent-soft);color:var(--fg-1) }
.su-run > .ent-input{ flex:1;min-width:0 }
.su-run-add,.su-blocks{ display:flex;flex-wrap:wrap;gap:7px;margin:8px 0 }
.su-preview{ display:flex;flex-direction:column;gap:5px;margin:12px 0 4px;padding:10px 12px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-2) }
.su-preview-k{ font:800 9.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3) }
.su-preview-v{ font:500 13.5px/1.6 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty;word-break:break-word }
.su-seg{ flex-wrap:wrap;margin-bottom:9px }
.su-seg button,.su-seg2 button{ min-height:34px;font-size:11.5px }
/* ── the values pane ── */
.su-var{ display:flex;flex-direction:column;gap:6px;padding:10px 11px;margin-bottom:9px;
  border:1px solid var(--border);border-radius:13px;background:var(--bg-1) }
.su-var.is-live{ border-color:color-mix(in srgb,var(--accent) 30%,var(--border)) }
.su-var-h{ display:flex;align-items:baseline;justify-content:space-between;gap:9px }
.su-var-nm{ font:800 12.5px/1.25 var(--mk-font-ui);color:var(--fg-1);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap }
.su-var-v{ flex:0 0 auto;font:800 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.su-var.is-live .su-var-v{ color:var(--fg-1) }
.su-var-f{ display:flex;align-items:center;gap:5px;font:600 11px/1.35 var(--mk-font-ui);color:var(--fg-2) }
.su-var-f .mi{ font-size:14px;color:var(--fg-3) }
.su-var-a{ display:flex;align-items:center;gap:6px }
.su-var-u{ flex:1;min-width:0;font:600 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
button.wl-chip.su-add{ width:100%;justify-content:center;margin-bottom:6px }
.wl-sumbox.su-src{ cursor:pointer;min-height:48px }
.wl-sumbox.su-src:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.su-go{ flex:0 0 auto;font-size:18px;color:var(--fg-3) }
/* § M-43 — the three bands, and a raise must out-specify the floor it raises. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  .su-bar button.wl-chip,.su-blocks button.wl-chip,.su-run-add button.wl-chip,
  button.wl-chip.su-add,.su-present-bar button.wl-chip{ min-height:44px }
  .su-bar button.wl-chip.wk-ic-btn{ width:44px;height:44px }
  .su-bar-nm{ min-height:44px }
  button.su-rail-i{ min-height:44px }
  .su-seg button,.su-seg2 button{ min-height:44px }
  .su-c{ height:48px }
  .su-b{ padding:7px 8px }
  .su-run button.wl-chip{ min-height:44px }
  .su-card{ min-height:44px }
}
@media (max-width:600px){
  .su-grid-cards{ grid-template-columns:1fr }
  .su-doc{ max-width:100%;padding-inline:0 }
  .su-b-h1{ font-size:21px }
  .su-b-h2{ font-size:16px }
  .su-b-p,.su-b-ul{ font-size:14.5px }
  .su-bar-nm{ max-width:min(58vw,300px) }
  .su-present{ padding:10px }
}

/* § S-16 joins this list rather than inventing a second mechanism: the inspector
   IS a panel below 1000px, and the FAB is a SIBLING of #shell (a body child), so
   a `.body.…` class on the app root could never have reached it — which is why
   every rule here is written as `body:has(…)`. */
body:has(.wk-body.side-open) .route-fab,
/* Present is on the preview floor, above every panel and below only a
   confirmation — so the FAB is gone under it too (§ M-88). */
body.su-presenting .route-fab,
body.su-presenting .page-fab,
body:has(.wk-body.side-open) .page-fab,
body:has(.panel-scrim.open) .route-fab,
body:has(#panelScrim.open) .route-fab,
body:has(.modal-overlay.open) .route-fab,
body:has(.wl-modal-scrim.open) .route-fab,
/* B63-008 — an open chat thread has its own composer at the same corner
   of the screen; the create FAB covered it and blocked sending messages
   on mobile. Chat doesn't need "create a new conversation" from in here
   anyway. */
body:has(.body[data-page="chat"] .chat.show-thread) .route-fab,
/* Audit A13 — an open Suite document is being written on; the Create FAB sat
   on the text (same reason as the chat thread above). */
body:has(.page-view[data-view="drive"].dr-editing) .route-fab,
/* Audit S5 — the event/meeting drawer (`.dwr`) is a panel too: the FAB sat on
   top of it on phones (layering: the FAB shows over main content only). */
body:has(.dwr.on) .route-fab,
body:has(.dwr.on) .page-fab,
body:has(.panel-scrim.open) .page-fab,
body:has(#panelScrim.open) .page-fab,
body:has(.modal-overlay.open) .page-fab,
body:has(.wl-modal-scrim.open) .page-fab{ display:none !important; }
/* C11 — required-by-default color-codes the TYPE chip (no 'req' chip) */
.nt-chip.nt-chip-req { background: var(--accent-soft); color: var(--accent-text); }
/* B52-03 — the relation's target location, as a jump chip. Same crumb parts
   (.ec-seg / .ec-sep / .ec-more) as the entity panel's breadcrumb, so a
   relation reads exactly like a path everywhere it appears. */
.nt-rel{ display:inline-flex;align-items:center;gap:4px;margin-inline-start:6px;padding:2px 8px;border-radius:999px;
  border:1px solid color-mix(in srgb,var(--accent) 26%,var(--border));background:var(--accent-soft);
  font:600 10.5px var(--mk-font-ui);color:var(--accent-text);cursor:pointer;max-width:260px;overflow:hidden;white-space:nowrap; }
.nt-rel:hover{ border-color:var(--accent);background:color-mix(in srgb,var(--accent) 18%,transparent); }
.nt-rel .ec-seg{ color:inherit;font-weight:600; }
.nt-rel .ec-seg.ec-cur{ font-weight:800; }
.nt-rel .ec-sep{ opacity:.6; }
.nt-rel .ec-more{ padding:0 5px;border-radius:999px;background:color-mix(in srgb,var(--accent) 22%,transparent);
  font:800 9.5px var(--mk-font-ui);color:inherit;border:0; }
.nt-rel .nt-rel-go{ font-size:13px;opacity:.75; }
.nt-rel:hover .nt-rel-go{ opacity:1; }
@media (pointer:coarse),(max-width:520px){ .nt-rel{ min-height:44px; } }
/* the flash that lands on the jump target */
.nt-box.nt-focus{ outline:2px solid var(--accent);outline-offset:1px;background:var(--accent-soft) !important;
  animation:ntFocusPulse 1.5s var(--mk-ease) both; }
@keyframes ntFocusPulse{ 0%,55%{ box-shadow:0 0 0 6px color-mix(in srgb,var(--accent) 22%,transparent) } 100%{ box-shadow:0 0 0 0 transparent } }
/* B39 C11 — staging chip + env-gated deploy/read-only on staging-flagged nodes */
.nt-chip.nt-chip-staging{ display:inline-flex;align-items:center;gap:3px;background:color-mix(in srgb,var(--mk-staging,#22a06b) 16%,transparent);color:var(--mk-staging,#22a06b);border-color:color-mix(in srgb,var(--mk-staging,#22a06b) 35%,transparent); }
.nt-chip.nt-chip-staging .mi{ font-size:12px; }
/* B63 W9 (149) — the Application's design-system badge (a small colour dot +
   the system's name, read live off MoccaDesignSystems) and the "no template"
   flag the sample states in red for a leaf with no component calls. */
.nt-chip.nt-chip-ds{ display:inline-flex;align-items:center;gap:5px; }
.nt-chip-ds-dot{ width:8px;height:8px;border-radius:50%;flex:0 0 auto; }
.nt-chip.nt-chip-tpl-missing{ display:inline-flex;align-items:center;gap:3px;background:color-mix(in srgb,var(--mk-danger) 12%,transparent);color:var(--mk-danger);border-color:color-mix(in srgb,var(--mk-danger) 40%,transparent); }
.nt-chip.nt-chip-tpl-missing .mi{ font-size:12px; }
.nt-deploy{ color:var(--mk-staging,#22a06b); }
.nt-deploy:hover{ background:color-mix(in srgb,var(--mk-staging,#22a06b) 16%,transparent);color:var(--mk-staging,#22a06b); }
.nt-staging .nt-deploy{ display:none; }
body[data-env="staging"] .nt-staging .nt-deploy{ display:grid; }
/* B40 C17/C18/C19 (Pablo) — ALL builder surfaces are staging services: every
   tree box carries its add/edit/remove buttons (no per-node gating — C19), and
   the WHOLE edit affordance set exists only on the staging env. Production is
   read-only: no row actions, no root add, no node-panel Edit. */
body:not([data-env="staging"]) .be-tree .nt-acts,
body:not([data-env="staging"]) .be-tree .nt-add-root,
body:not([data-env="staging"]) #nodeViewPanel [data-nv-edit],
body:not([data-env="staging"]) #routeEditPanel [data-route-hd-edit]{ display:none !important; }
.ent-type-chip.ent-req-def { background: var(--accent-soft); color: var(--accent-text); }
.ent-f-type.ent-req-def { background: var(--accent-soft); color: var(--accent-text); border-radius: 999px; padding: 1px 8px; }
/* C7 — field-form section headers + per-field read/write permissions */
.ent-sech { display: flex; align-items: center; gap: 8px; margin: 20px 0 8px; padding-top: 14px; border-top: 1px solid var(--border); font-size: 12.5px; font-weight: 700; color: var(--fg-1); }
.ent-panel-body > .ent-sech:first-child, .ent-sech:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.ent-sech > .mi { font-size: 17px; color: var(--fg-3); }
.ent-sech-i { margin-inline-start: auto; }
/* ── B50-10 — vertical rhythm in the entity/field panel body ─────────────────
   Pablo: "I need some spacing here all the items are too close together, this is
   also something the visual check should've been able to catch."
   The field form appends its controls DIRECTLY to `.ent-panel-body` (24 siblings
   deep on a form field), and only `.ent-form-lbl` and `.ent-sech` carried any
   margin — so an input followed by a collection body followed by an "Add …"
   button stacked with literally zero space. A single owl rule sets a FLOOR of
   9px between every pair of siblings; because this is block flow, adjacent
   margins collapse, so the deliberately larger gaps (a section header's 20px)
   still win and nothing else has to change. */
.ent-panel-body > * + *{ margin-top:9px; }
/* A label must keep hugging its own control — the label's 5px wins there. */
.ent-panel-body > .ent-form-lbl + *{ margin-top:0; }
/* An "Add …" button that closes a collection gets a touch more air above it, so
   it reads as an action on the list rather than another row of it. */
.ent-panel-body > .ent-coll-body + .ent-coll-add,
.ent-panel-body > .ent-coll-body + .ent-subadd{ margin-top:11px; }
.ent-perm-rw { display: flex; align-items: center; gap: 10px; }
.ent-perm-rw .ent-perm-role-nm { flex: 1 1 auto; min-width: 0; }
.ent-perm-rw .ent-tri { flex: 0 0 auto; }
.ent-perm-head { margin-bottom: 2px; min-height: 0; }
.ent-perm-head .ent-perm-cap { flex: 0 0 auto; width: 88px; text-align: center; font-size: 10.5px; font-weight: 700; color: var(--fg-3); }
.ent-ex-list { display: flex; flex-direction: column; gap: 6px; }

/* ── B35 S1 — route preview (single source of truth) + shell config ── */
/* B40 C7/C8 — the preview lives OUTSIDE the panel: desktop = left dock
   (reuses .cmp-preview-dock); mobile/tablet = fullscreen behind the header
   eye button (.fs-open). The in-panel .rt-preview block is gone. */
.rt-pv-host{ z-index:1240; } /* above the route panel scrim, below the panel */
.rt-pv-dock-mount{ flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;align-items:center;padding:26px;overflow:auto; }
.rt-pv-host .rt-pv-bar{ margin-bottom:12px; }
.rt-pv-host .rt-pv-title{ color:#dfe6f0; }
/* B50-24 — the stage's radius MUST match the frame's (14px). At the old 8px the
   frame's larger corner radius exposed the stage plate in each corner — four
   little pale wedges, which is part of what read as "whitespace between the
   preview and the frame". The frame owns the shadow; the stage owns nothing but
   the clip. */
.rt-pv-host .rt-pv-stage{ background:transparent;box-shadow:none;border-radius:14px; }
@media (max-width:600px),
       (max-height:599px) and (orientation:landscape),
       (min-width:601px) and (max-width:1024px) and (min-height:600px){
  /* fullscreen preview overlay on mobile/tablet — wins over the dock's
     display:none!important media rule via id specificity + later sheet */
  aside#rtPreviewDock.fs-open{ display:flex !important;opacity:1;position:fixed;inset:0 !important;z-index:1500; }
}
/* the header eye button only makes sense where the dock is hidden */
@media (min-width:1025px), (min-width:601px) and (max-height:599px) and (orientation:landscape){
  #routeEditPanel [data-route-hd-preview]{ display:none; }
}
.rt-preview{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:10px;margin-bottom:14px;background:var(--bg-2,#f7f8fa);overflow:hidden; }
.rt-pv-bar{ display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;gap:8px; }
.rt-pv-title{ display:inline-flex;align-items:center;gap:6px;font:700 12px/1 var(--mk-font-ui);color:var(--fg-2); }
.rt-pv-title .mi{ font-size:16px; }
.rt-pv-vps{ display:inline-flex;gap:2px;border:1px solid var(--bd-1,#dfe4e8);border-radius:8px;overflow:hidden;background:var(--bg-1,#fff); }
.rt-pv-vp{ border:none;background:transparent;padding:4px 8px;cursor:pointer;color:var(--fg-3);display:inline-flex;align-items:center; }
.rt-pv-vp .mi{ font-size:16px; }
.rt-pv-vp.on{ background:var(--accent);color:#fff; }
/* B50-24 — the stage IS the scaled device frame's box (sized in sections.js) and
   is centred in the mount, so there is no dead strip between the preview and the
   frame. `min-height` is intentionally absent: a floor would re-introduce the gap. */
.rt-pv-stage{ position:relative;overflow:hidden;border-radius:14px;flex:0 0 auto;align-self:center;max-width:100%; }
.rt-pv-frame{ transform-origin:top left;display:flex;flex-direction:column;gap:10px;position:absolute;top:0;left:0; }
[dir="rtl"] .rt-pv-frame{ transform-origin:top right;left:auto;right:0; }
.rt-pv-cell{ background:var(--bg-1,#fff);border:1px dashed color-mix(in srgb,var(--fg-3,#8a94a6) 35%,transparent);border-radius:10px;padding:8px;overflow:hidden; }
.rt-pv-err{ display:inline-flex;align-items:center;gap:6px;color:#c0392b;font:600 12px/1 var(--mk-font-ui); }
.rt-pv-empty{ padding:14px;border:1px dashed var(--bd-1,#dfe4e8);border-radius:12px;color:var(--fg-3);font:500 12px/1.4 var(--mk-font-ui);margin-bottom:14px;text-align:center; }
.rt-pv-shell{ width:100%; }
.rt-pv-shell.rt-pv-cell{ border:0;padding:0;background:transparent; }
.rt-pv-slot-empty{ display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:120px;border:2px dashed color-mix(in srgb,var(--fg-3,#8a94a6) 30%,transparent);border-radius:12px;color:var(--fg-3);font:600 13px/1.3 var(--mk-font-ui); }
.rt-pv-slot-empty .mi{ font-size:26px;color:color-mix(in srgb,var(--accent) 55%,var(--fg-3)); }
.rt-pv-slot-empty small{ font-weight:500;opacity:.8; }
.rt-sh-togs{ display:flex;flex-wrap:wrap;gap:7px;margin-bottom:10px; }
.rt-sh-tog{ display:inline-flex;align-items:center;gap:5px;padding:6px 11px;border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;background:var(--bg-1,#fff);cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.rt-sh-tog .mi{ font-size:15px; }
.rt-sh-tog.on{ border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent); }
.rt-sh-f{ display:block;margin-bottom:10px; }

/* ── B35 S8 — Wallet (Balance / Expenses / Trips) ── */
.wl-kpis{ display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:22px; }
@media (max-width:700px){ .wl-kpis{ grid-template-columns:1fr; } }
/* B37 C3 (Pablo, "add some flare") — tone-tinted gradient wash, oversized
   tabular numerals, oversized watermark glyph, accent hairline. Tones ride
   an oklch hue var so they stay harmonious with the theme. */
.wl-kpi{ --klh:255; position:relative;overflow:hidden;border:1px solid color-mix(in oklch, oklch(62% .13 var(--klh)) 26%, var(--bd-1,#dfe4e8));border-radius:18px;padding:18px 20px 16px;
  background:linear-gradient(135deg, color-mix(in oklch, oklch(62% .13 var(--klh)) 12%, var(--bg-1,#fff)) 0%, var(--bg-1,#fff) 55%, color-mix(in oklch, oklch(70% .1 var(--klh)) 7%, var(--bg-1,#fff)) 100%); }
.wl-kpi::after{ content:'';position:absolute;inset:auto 0 0 0;height:3px;background:linear-gradient(90deg, oklch(62% .15 var(--klh)) 0%, transparent 78%);opacity:.75; }
.wl-kpi-bal{ --klh:255; } .wl-kpi-debt{ --klh:25; } .wl-kpi-owed{ --klh:155; }
/* B39 C38 (Pablo) — darker saturated fill + lighter font for more contrast; no icon, no caps. */
.wl-kpi{ background:linear-gradient(140deg, oklch(45% .13 var(--klh)) 0%, oklch(36% .12 var(--klh)) 100%) !important;border-color:oklch(40% .12 var(--klh)) !important; }
.wl-kpi::after{ opacity:.5;background:linear-gradient(90deg, oklch(80% .16 var(--klh)) 0%, transparent 78%); }
.wl-kpi-h{ text-transform:none !important;letter-spacing:0 !important;font-weight:600;font-size:13px;color:rgba(255,255,255,.72) !important; }
.wl-kpi-line{ color:#fff !important; }
.wl-kpi-line + .wl-kpi-line{ color:rgba(255,255,255,.7) !important; }
.wl-kpi-line.pos{ color:#7ee2a8 !important; } .wl-kpi-line.neg{ color:#ffb3b3 !important; } .wl-kpi-line.dim{ color:rgba(255,255,255,.6) !important; }
.wl-kpi-wm{ position:absolute;inset-inline-end:-14px;top:-16px;font-size:96px;line-height:1;color:oklch(62% .14 var(--klh));opacity:.08;pointer-events:none; }
[dir="rtl"] .wl-kpi-wm{ transform:scaleX(-1); }
.wl-kpi-h{ display:flex;align-items:center;gap:7px;font:700 11.5px/1 var(--mk-font-ui);color:color-mix(in oklch, oklch(48% .12 var(--klh)) 72%, var(--fg-3));text-transform:none;letter-spacing:.09em;margin-bottom:12px; }
.wl-kpi-h .mi{ font-size:17px;color:oklch(58% .15 var(--klh)); }
.wl-kpi-v{ display:flex;flex-direction:column;gap:3px; }
.wl-kpi-line{ font:800 30px/1.15 var(--mk-font-ui);letter-spacing:-.02em;color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-kpi-line + .wl-kpi-line{ font-size:19px;color:var(--fg-2); }
.wl-kpi-line.pos{ color:var(--mk-ok,#2f9e63); } .wl-kpi-line.neg{ color:var(--mk-danger,#d64545); } .wl-kpi-line.dim{ color:var(--fg-3);font-weight:600; }
.wl-sech{ display:flex;align-items:center;gap:7px;font:700 12.5px/1 var(--mk-font-ui);color:var(--fg-2);margin:18px 0 10px; }
/* B40 C33 — section-header icons follow the SHELL's neutral icon tone. */
.wl-sech .mi{ font-size:17px;color:var(--fg-3); }
.wl-list{ display:flex;flex-direction:column;gap:8px; }
.wl-row{ display:flex;align-items:center;gap:11px;padding:11px 14px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff); }
.wl-row.sm{ padding:8px 11px; }
.wl-click{ cursor:pointer;transition:border-color .15s, box-shadow .15s; }
.wl-click:hover{ border-color:var(--accent);box-shadow:0 3px 12px color-mix(in srgb,var(--accent) 12%,transparent); }
.wl-row-main{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px; }
.wl-row-nm{ font:600 13.5px/1.2 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.wl-row-sub{ font:500 11.5px/1.3 var(--mk-font-ui);color:var(--fg-3);display:flex;align-items:center;gap:4px;flex-wrap:wrap; }
.wl-dir{ font:600 12px/1 var(--mk-font-ui);color:var(--fg-3);flex:0 0 auto; }
.wl-amt{ font:800 14px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;flex:0 0 auto; }
.wl-amt.pos{ color:var(--mk-ok,#2f9e63); } .wl-amt.neg{ color:var(--mk-danger,#d64545); }
.wl-cur{ font:700 10.5px/1 var(--mk-font-ui);padding:3px 7px;border-radius:999px;border:1px solid var(--bd-1,#dfe4e8);color:var(--fg-3);flex:0 0 auto; }
.wl-av{ width:28px;height:28px;flex:0 0 auto;border-radius:50%;display:inline-grid;place-items:center;font:700 10.5px var(--mk-font-ui);background:oklch(.9 .06 var(--wl-h));color:oklch(.4 .12 var(--wl-h)); }
.wl-av.sm{ width:22px;height:22px;font-size:9px; }
.wl-avs{ display:inline-flex;flex:0 0 auto; } .wl-avs .wl-av{ margin-inline-start:-6px;border:2px solid var(--bg-1,#fff); } .wl-avs .wl-av:first-child{ margin-inline-start:0; }
.wl-ic{ width:32px;height:32px;flex:0 0 auto;border-radius:9px;display:inline-grid;place-items:center;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent);font-size:18px; }
.wl-triptag{ display:inline-flex;align-items:center;gap:3px;color:var(--accent);font-weight:600; }
.wl-triptag .mi{ font-size:13px; }
.wl-seg{ margin-bottom:14px; }
.wl-empty{ padding:16px;border:1px dashed var(--bd-1,#dfe4e8);border-radius:12px;color:var(--fg-3);font:500 12.5px/1.4 var(--mk-font-ui);text-align:center; }
.wl-cards{ display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:12px; }
.wl-card{ display:flex;flex-direction:column;gap:9px;padding:15px 16px;border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff); }
.wl-card-h{ display:flex;align-items:center;gap:8px;justify-content:space-between; }
.wl-card-nm{ font:700 14.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-status{ display:inline-flex;align-items:center;gap:4px;font:700 10.5px/1 var(--mk-font-ui);padding:4px 9px;border-radius:999px;flex:0 0 auto; }
.wl-status .mi{ font-size:13px; }
.wl-st-upcoming{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.wl-st-active{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 14%,transparent);color:var(--mk-ok,#2f9e63); }
.wl-st-ended{ background:color-mix(in srgb,#d9a400 16%,transparent);color:#a67c00; }
.wl-st-closed{ background:var(--bg-2,#f4f5f7);color:var(--fg-3); }
.wl-card-meta{ display:flex;align-items:center;gap:5px;font:500 12px/1.3 var(--mk-font-ui);color:var(--fg-3);flex-wrap:wrap; }
.wl-card-meta .mi{ font-size:14px; } .wl-dot{ margin:0 2px; }
.wl-card-foot{ display:flex;align-items:center;justify-content:space-between;gap:8px; }
.wl-spend{ font:700 12.5px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wallet-panel{ z-index:1205; } .wallet-scrim{ z-index:1204; }
.wl-meta-row{ display:flex;flex-wrap:wrap;gap:7px;margin-bottom:6px; }
.wl-chip{ display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:999px;border:1px solid var(--bd-1,#dfe4e8);background:var(--bg-1,#fff);font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.wl-chip .mi{ font-size:14px;color:var(--fg-3); } .wl-chip.sm{ padding:4px 9px; }
/* B40 C40 — every wl-chip that is a BUTTON gets pointer + hover feedback. */
button.wl-chip{ cursor:pointer;transition:border-color var(--mk-t-fast),background var(--mk-t-fast),color var(--mk-t-fast); }
button.wl-chip:hover{ border-color:var(--fg-3);background:var(--bg-2,#f4f6f8);color:var(--fg-1); }
/* 44px hit-target floor (Pablo, 2026-08-26) — only the INTERACTIVE chips get it:
   a static `span.wl-chip` in a meta row is not a target, and inflating it would
   change chrome for no reason. Padding carries most of it so the pill keeps its
   shape, and the ::after is vertical-only so wrapped rows never overlap
   horizontally. */
button.wl-chip,a.wl-chip{position:relative;padding-block:9px;min-height:40px}
button.wl-chip::after,a.wl-chip::after{content:'';position:absolute;inset:-2px 0}
.wl-chips{ display:flex;flex-wrap:wrap;gap:6px; }
.wl-item{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:11px 13px;margin-bottom:8px;background:var(--bg-1,#fff); }
.wl-item-h{ display:flex;align-items:center;gap:9px; }
.wl-item-nm{ flex:1;font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-item-math{ font:500 11.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.wl-item-cons{ display:flex;flex-direction:column;gap:6px;margin-top:9px;padding-top:9px;border-top:1px dashed var(--bd-1,#dfe4e8); }
.wl-con{ display:flex;align-items:center;gap:8px; }
.wl-con-nm{ flex:1;font:500 12.5px/1.2 var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.wl-mode{ display:inline-flex;align-items:center;gap:4px;font:600 10.5px/1 var(--mk-font-ui);padding:3px 8px;border-radius:999px;flex:0 0 auto; }
.wl-mode .mi{ font-size:12px; }
.wl-mode-self{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 13%,transparent);color:var(--mk-ok,#2f9e63); }
.wl-mode-invited{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.wl-mode-covering{ background:color-mix(in srgb,#a06bd8 15%,transparent);color:#8a4fd0; }
.wl-mode-pays{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.wl-mode-cons{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 13%,transparent);color:var(--mk-ok,#2f9e63); }
.wl-conv-note{ display:flex;align-items:center;gap:6px;font:500 11.5px/1.3 var(--mk-font-ui);color:var(--fg-3);margin:2px 0 4px; }
.wl-conv-note .mi{ font-size:14px; }
.wl-amt-orig{ font:500 11.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums;margin-inline-end:2px; }
.wl-acct-flag{ line-height:1;flex:0 0 auto;display:inline-flex; }
/* B50-19 (Pablo: "I want a 1:1 aspect ratio on these country icons and also
   cropped in a circular shape") — the flag was a 26×18 rectangle. It is now a
   square circular crop: the SVG keeps its own 3:2 aspect (never squashed) and
   overflows the round box horizontally, centred, so the middle of the flag shows. */
.wl-flag{ display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;aspect-ratio:1;border-radius:50%;overflow:hidden;box-shadow:0 0 0 1px rgba(0,0,0,.1);flex:0 0 auto; }
.wl-flag svg{ height:100%;width:auto;min-width:100%;flex:0 0 auto;display:block; }
.wl-flag-fallback{ width:20px;height:20px;border-radius:50%;align-items:center;justify-content:center;background:var(--bg-2,#eef1f4);color:var(--fg-3);font-size:13px; }
.wl-mode-x{ font-weight:500;opacity:.85; }
.wl-share{ font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums;flex:0 0 auto; }
.wl-totals{ margin-top:4px;border-top:2px solid var(--bd-1,#dfe4e8);padding-top:10px;display:flex;flex-direction:column;gap:6px; }
.wl-total-row{ display:flex;justify-content:space-between;align-items:center;gap:10px;font:600 12.5px/1.35 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wl-total-row > span:first-child{ display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap; }
.wl-total-row .mi{ font-size:15px;color:var(--fg-3); }
.wl-total-final{ font:800 14.5px/1 var(--mk-font-ui);color:var(--fg-1); }
/* B37 C1/C2 — fee rows, item additions + the expense edit form */
.wl-disc{ color:var(--mk-ok,#2f9e63); }
/* the section-header RULE ("optional — but it owns the nights") — content */
.wl-fee-note{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-2); }
/* B42 Q5 — live FX rate provenance under the currency selector */
.wl-fx-note{ display:flex;align-items:center;gap:6px;margin-top:-2px;font:600 11px/1.3 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.wl-fx-note .mi{ font-size:15px;color:var(--mk-accent,#2A8C8A); }
/* B42 Q9 — trip running estimate row (expense-editor parity) */
.wl-trip-est{ margin-top:4px;border-radius:10px; }
.wl-trip-est > span:first-child{ display:flex;align-items:center;gap:6px; }
.wl-trip-est .mi{ font-size:16px;color:var(--fg-3); }
.wl-item-add{ display:flex;align-items:center;gap:7px;margin-top:7px;font:500 12px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wl-item-add .mi{ font-size:15px;color:var(--fg-3); }
.wl-item-add > span:nth-child(2){ flex:1; }
.wl-item-add .wl-amt.pos{ color:var(--mk-ok,#2f9e63); }
.wl-panel-ft{ display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--bd-1,#dfe4e8);background:var(--bg-1,#fff); }
.wl-form{ display:flex;flex-direction:column;gap:10px; }
/* ── B50-08 — the wallet editor states where it stores ─────────────────────
   A movement IS the `fm_money` form, so the editor opens with the same
   provenance banner the entity panel uses. Same grammar in both places, so the
   claim "the prototype renders from the model" is visible, not just asserted. */
.wl-reg-banner{ display:flex;align-items:center;gap:7px;padding:8px 11px;border-radius:9px;
  background:var(--accent-soft);border:1px solid color-mix(in srgb,var(--accent) 22%,transparent);
  font:500 11.5px var(--mk-font-ui);color:var(--fg-2); }
.wl-reg-banner .mi{ font-size:15px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.wl-reg-banner b{ color:var(--fg-1);font-weight:800; }
.wl-reg-banner code{ font:600 10.5px var(--mk-font-mono,ui-monospace,monospace);color:var(--fg-2);
  background:var(--bg-1);padding:1px 5px;border-radius:5px; }
/* The required marker comes from the resolved field layer; its tooltip names
   which layer set it. */
.wl-req{ color:var(--accent-text,var(--accent));font-weight:800;margin-inline-start:3px; }
/* B50-08 — the same required marker on a registry-driven TABLE header. */
.th-req{ color:var(--accent-text,var(--accent));font-weight:800;margin-inline-start:2px; }
/* The provenance banner on a full page (not inside a panel) sits with the page
   rhythm rather than the form's. */
.sec-reg-banner{ margin:0 0 14px; }
/* WAVE 2 — the provenance line inside the two chat surfaces. Both sit in flex
   columns, so it must not stretch or absorb the column gap. */
.ct-reg-banner{ margin:0 0 10px;flex:0 0 auto;align-self:stretch; }
.cl-reg-banner{ margin:10px 12px 0; }

.wl-frow{ display:flex;flex-direction:column;gap:5px; }
/* a form label is never decorative */
.wl-frow label{ font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2);text-transform:none;letter-spacing:.05em; }
.wl-frow-2{ display:grid;grid-template-columns:1fr 1fr;gap:10px; } .wl-frow-2 > span{ display:flex;flex-direction:column;gap:5px; }
/* B63-053 — a currency "bubble" (the flag-enhanced `.cs` select) beside a
   plain amount input, the same grammar as a phone number's country-code
   bubble + number. */
.wl-cur-amt{ display:flex;gap:8px }
.wl-cur-amt select.ent-input{ flex:0 0 92px }
.wl-cur-amt input.ent-input{ flex:1;min-width:0 }
.wl-frow-3{ display:grid;grid-template-columns:1fr 76px 110px;gap:8px; }
.ent-input.sm{ height:30px;font-size:12px;padding:0 8px; } .ent-input.num{ font-variant-numeric:tabular-nums; }
.wl-req{ border-color:var(--mk-danger,#d64545) !important; }
.wl-part-ed{ display:flex;flex-direction:column;gap:7px;border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;padding:8px 10px; }
.wl-part-top{ display:flex;align-items:center;gap:8px; }
.wl-part-top select{ flex:1;min-width:0; }
.wl-part-rel{ display:flex;align-items:center;flex-wrap:wrap;gap:6px;padding-top:6px;border-top:1px dashed var(--bd-1,#dfe4e8); }
.wl-part-rel.req{ border-top-color:color-mix(in srgb,var(--mk-danger,#d64545) 55%,transparent); }
.wl-part-rel.req .wl-mini-l{ color:var(--mk-danger,#d64545); }
.wl-mode-for{ color:var(--accent); } .wl-mode-by{ color:var(--mk-ok,#2f9e63); }
.wl-toggles{ display:flex;gap:6px;flex:0 0 auto; }
.wl-tog{ display:inline-flex;align-items:center;gap:4px;font:600 11px/1 var(--mk-font-ui);padding:6px 10px;border-radius:999px;border:1px solid var(--bd-1,#dfe4e8);background:var(--bg-1,#fff);color:var(--fg-3);cursor:pointer;transition:.14s; }
.wl-tog .mi{ font-size:14px; }
.wl-tog:hover{ border-color:var(--fg-3); }
.wl-tog.on{ background:color-mix(in srgb,var(--accent) 12%,transparent);border-color:color-mix(in srgb,var(--accent) 40%,transparent);color:var(--accent); }
/* P4-MP-01 — at narrow (mobile-portrait) widths the participant row keeps the
   avatar + name-select + remove-× on line 1 and wraps the Pays/Consumes toggles
   to a full-width 2nd line, so the expense-editor panel-body never gains a
   horizontal scrollbar. `order` keeps × beside the select (DOM order puts it
   after the toggles). Scoped ≤480px so tablet/desktop stay single-line. */
@media (max-width:480px){
  .wl-part-top{ flex-wrap:wrap; }
  .wl-part-top .wl-cs{ flex:1 1 0;min-width:0; }
  .wl-part-top .wl-x{ order:2; }
  .wl-part-top .wl-toggles{ order:3;flex-basis:100%; }
}
.wl-item-ed{ display:flex;flex-direction:column;gap:8px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:11px 13px;background:var(--bg-1,#fff); }
.wl-add-row{ display:flex;gap:8px; } .wl-add-row .ent-input{ flex:1; }
.wl-chips-ed .wl-chip{ display:inline-flex;align-items:center;gap:4px; } .wl-chips-ed .wl-x{ margin-inline-start:2px; }
.wl-item-ed-ft{ display:flex;justify-content:space-between;align-items:center;gap:8px; }
.wl-cons-ed{ display:flex;flex-wrap:wrap;gap:6px; }
/* B39 C40/C45 — native <select> replaced by the .cs dropdown; hide the native
   element but keep it in the DOM as the value source. */
.wl-cs-native{ display:none !important; }
.wl-cs{ position:relative;width:100%; }
.wl-cs .cs-btn{ display:flex;align-items:center;gap:8px;width:100%;box-sizing:border-box;min-height:40px;padding:8px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;background:var(--bg-input,var(--bg-1));cursor:pointer;font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-cs.wl-cs-sm .cs-btn{ min-height:34px;padding:6px 10px;font-size:12px; }
.wl-cs .cs-btn:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--bd-1,#dfe4e8)); }
.wl-cs .cs-val{ flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start; }
.wl-cs .cs-arrow{ font-size:18px;color:var(--fg-3);flex:0 0 auto;transition:transform .15s; }
.wl-cs.open .cs-arrow{ transform:rotate(180deg); }
.wl-cs .cs-menu{ display:none;position:absolute;z-index:60;top:calc(100% + 4px);left:0;right:0;max-height:240px;overflow-y:auto;padding:5px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);box-shadow:0 12px 32px rgba(0,0,0,.16);flex-direction:column;gap:2px; }
.wl-cs.open .cs-menu{ display:flex; }
.wl-cs .cs-item{ padding:8px 10px;border-radius:8px;cursor:pointer;font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);white-space:nowrap; }
.wl-cs .cs-item:hover{ background:var(--accent-soft); }
.wl-cs .cs-item.on{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-text,var(--accent)); }
/* B39 C27 — multi-select input (selected chips + Add dropdown). */
.wl-ms{ position:relative;margin-bottom:2px; }
.wl-ms-field{ display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:40px;padding:6px 8px;border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;background:var(--bg-input,var(--bg-1)); }
.wl-ms-chip{ display:inline-flex;align-items:center;gap:6px;padding:3px 4px 3px 4px;border-radius:999px;background:color-mix(in srgb,var(--accent) 9%,transparent);border:1px solid color-mix(in srgb,var(--accent) 22%,transparent);font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-1); }
.wl-ms-chip .wl-ms-nm{ padding-inline-end:2px; }
.wl-ms-chip{ display:inline-flex;align-items:center;gap:6px;padding:3px 4px 3px 4px;border-radius:999px;background:color-mix(in srgb,var(--accent) 9%,transparent);border:1px solid color-mix(in srgb,var(--accent) 25%,transparent);font:600 12px/1 var(--mk-font-ui);color:var(--fg-1);max-width:100%;min-width:0; }
.wl-ms-chip .wl-ms-nm{ padding-inline-end:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0; }
/* B40 C32 — the chip's X can never overflow: fixed square, never shrinks,
   overflow clipped by the pill radius. */
.wl-ms-x{ display:grid;place-items:center;width:16px;height:16px;flex:0 0 16px;border:0;border-radius:50%;background:none;cursor:pointer;color:var(--fg-3);padding:0;overflow:hidden; }
.wl-ms-x:hover{ background:color-mix(in srgb,var(--mk-err,#c0392b) 16%,transparent);color:var(--mk-err,#c0392b); }
.wl-ms-x .mi{ font-size:13px; }
.wl-ms-ph{ color:var(--fg-3);font:500 12.5px/1 var(--mk-font-ui); }
.wl-ms-add{ display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border:1px dashed color-mix(in srgb,var(--accent) 45%,var(--bd-1,#dfe4e8));border-radius:999px;background:none;cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--accent-text,var(--accent)); }
.wl-ms-add .mi{ font-size:14px; }
.wl-ms-menu{ position:absolute;z-index:40;top:calc(100% + 4px);left:0;min-width:200px;max-height:230px;overflow-y:auto;padding:5px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);box-shadow:0 10px 30px rgba(0,0,0,.14);display:flex;flex-direction:column;gap:2px; }
/* B50-14 — the `hidden` attribute is what JS toggles on this menu, and a bare
   `display:flex` above silently defeats it (same systemic trap as
   .page-fab-item). Without this guard the people picker is permanently open. */
.wl-ms-menu[hidden]{ display:none; }
.wl-ms-opt{ display:flex;align-items:center;gap:8px;padding:7px 9px;border:0;border-radius:8px;background:none;cursor:pointer;font:600 12.5px/1 var(--mk-font-ui);color:var(--fg-1);text-align:start; }
.wl-ms-opt:hover{ background:var(--accent-soft); }
.wl-cpick{ display:inline-flex;align-items:center;gap:5px;border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;padding:4px 9px 4px 5px;cursor:pointer;font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-3);opacity:.55; }
.wl-cpick.on{ opacity:1;border-color:var(--accent);color:var(--fg-1);background:color-mix(in srgb, var(--accent) 8%, transparent); }
.wl-pct{ width:40px;border:1px solid var(--bd-1,#dfe4e8);border-radius:7px;background:var(--bg-1,#fff);padding:3px 5px;font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-1);text-align:end;font-variant-numeric:tabular-nums; }
.wl-pct::placeholder{ color:var(--fg-3);font-weight:600; }
.wl-pct:focus{ outline:none;border-color:var(--accent); }
/* B40 C47 — % share box */
.wl-pctbox{ display:inline-flex;align-items:center;gap:2px;font:700 11px/1 var(--mk-font-ui);color:var(--fg-3); }
/* B40 C48 — photo avatars */
.wl-av-img{ background:var(--bg-2,#eef1f4);overflow:hidden; }
.wl-av-img img{ width:100%;height:100%;object-fit:cover;display:block;border-radius:50%; }
/* B40 C49/C44/C35 — summary BOXES (payments / fees / menus / stops) */
.wl-sumbox{ display:flex;align-items:center;gap:9px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);min-width:0; }
.wl-sumbox + .wl-sumbox{ margin-top:6px; }
.wl-sumbox-main{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px; }
.wl-sumbox-t{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
html[dir="rtl"] .wl-sumbox-t{ unicode-bidi:plaintext; text-align:right; }   /* B67 R25 (R67-098) — a Latin row title (a long dish / course name) cut at its START in Arabic (R67-014; shared — every summary row) */
/* B62 — a .wl-sumbox subtitle STATES A RULE (the Jockey views state the club's
   rules in it; the trip's Players row states who a late arrival's votes count
   for), and a rule pinned to one line loses its operative half to an ellipsis:
   measured 294px of text in a 246px box, with "weigh on the 21st and 22nd" —
   the whole point of the row — cropped away. § M-43 makes cropped information
   critical, so it wraps to two lines and only then clamps. The clamp keeps a
   runaway string from growing the box without bound; the ellipsis survives via
   -webkit-line-clamp, so nothing silently vanishes without a marker.
   The COLOUR is the other half of the same argument: --fg-3 is the tertiary /
   DISABLED tone (2.54:1 light, 3.88:1 dark at 11px), and a rule painted in the
   disabled tone is not a rule anyone can read. It takes --fg-2 (7.56:1 light,
   measured on the sibling .cn-swipe-meta fix this session). The one place that
   deliberately keeps --fg-3 is .rt-box.is-empty, where the text is a
   placeholder rather than something to read. */
.wl-sumbox-s{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-2);white-space:normal;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;text-overflow:ellipsis; }
/* .wl-sumbox is a <button> in most surfaces, and a button's width:auto is
   fit-content (the B62 wave-4 Jockey trap) — the wrap only helps if the row is
   actually allowed to be as narrow as its column. */
.wl-sumbox{ width:100%;min-width:0; }
.wl-sumbox-acts{ display:flex;gap:2px;flex:0 0 auto; }
.wl-ic-sm{ width:26px;height:26px;font-size:15px;border-radius:8px; }
/* B40 C50/C37 — shared datetime buttons */
.wl-dt-btn{ display:flex;align-items:center;gap:7px;cursor:pointer;text-align:start;width:100%; }
.wl-dt-btn .mi{ font-size:15px;color:var(--accent-text,var(--accent)); }
.wl-dt-btn:hover{ border-color:var(--accent); }
/* B40 C36 — multi-select search + Invite */
.wl-ms-search{ display:flex;align-items:center;gap:6px;padding:4px 7px;margin-bottom:4px;border:1px solid var(--bd-1,#dfe4e8);border-radius:8px;background:var(--bg-2,#f4f6f8); }
.wl-ms-search .mi{ font-size:14px;color:var(--fg-3); }
.wl-ms-search input{ border:0;background:none;outline:none;flex:1;min-width:0;font:600 12px/1 var(--mk-font-ui);color:var(--fg-1); }
/* B46 C32/C37 (Pablo: "the children of an app should also show the boxes" /
   "this shouldn't be a chip, it should be a list of boxes") — the count chip is
   gone; the children header carries the breakdown and the boxes ARE the value. */
.nv-kids-h{ margin-top:4px; }
/* B46 C12 (Pablo: "move the Weekdays / All-days selector to the shell — I want
   to leave the header alone with the truncation element") — the shell nav pill
   (#wkDaysShellBtn) is the single control. P6-27: the hide is now driven from
   the pill's own visibility in syncWkShellBtn() (size-agnostic — the pill is
   mounted at every width, icon-only when compact), because this media query
   left BOTH visible at mobile portrait. Kept as a no-JS fallback only. */
@media (min-width:601px){ .page-h .acts .wk-days-btn{ display:none; } }
/* B46 C08 — explicit close in the people dropdown (plus Esc + outside-click). */
.wl-ms-close{ position:relative;width:22px;height:22px;flex:0 0 auto;display:grid;place-items:center;border:0;border-radius:999px;background:none;color:var(--fg-3);cursor:pointer;padding:0; }
.wl-ms-close:hover{ background:color-mix(in srgb,var(--fg-1) 10%,transparent);color:var(--fg-1); }
.wl-ms-close .mi{ font-size:15px;line-height:1; }
/* Touch: extend the TAP TARGET to the 44px minimum without growing the glyph or
   pushing the compact search row taller (P6-28 — 32px was still under the bar). */
@media (pointer:coarse){
  .wl-ms-close::after{ content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:44px;height:44px;border-radius:999px; }
}
.wl-ms-opts{ display:flex;flex-direction:column;max-height:170px;overflow-y:auto; }
.wl-ms-invite{ display:flex;align-items:center;gap:8px;width:100%;padding:8px 9px;margin-top:3px;border:1px dashed color-mix(in srgb,var(--accent) 45%,var(--bd-1,#dfe4e8));border-radius:8px;background:none;cursor:pointer;font:600 12.5px/1 var(--mk-font-ui);color:var(--accent-text,var(--accent)); }
.wl-ms-invite .mi{ font-size:15px; }
/* B40 C52 — icons/avatars in dropdown options */
.cs-opt-mi{ font-size:15px;color:var(--fg-3);flex:0 0 auto; }
.wl-cs .cs-item{ display:flex;align-items:center;gap:7px; }
.wl-cs .cs-val{ display:inline-flex;align-items:center;gap:7px;min-width:0; }
.wl-cs .cs-item.on .cs-opt-mi{ color:var(--accent-text,var(--accent)); }
.cs-opt-t{ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0; }
/* B40 C43 — total in the FIXED footer */
.wl-ft-total{ display:flex;flex-direction:column;gap:1px;margin-inline-end:auto; }
.wl-ft-total-l{ font:700 10px/1 var(--mk-font-ui);color:var(--fg-3); }
.wl-ft-total-v{ font:800 15px/1.1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
/* B40 — wallet panel slides */
.wallet-panel{ overflow:hidden; }
.wallet-panel .wl-slide{ position:absolute;inset:0;z-index:6;display:flex;flex-direction:column;background:var(--bg-1,#fff);transform:translateX(100%);transition:transform .28s cubic-bezier(.32,.72,.28,1); }
[dir="rtl"] .wallet-panel .wl-slide{ transform:translateX(-100%); }
.wallet-panel .wl-slide.open{ transform:translateX(0); }
.wallet-panel .wl-slide .wl-panel-ft{ display:flex; }
.wl-slide .panel-hd{ display:flex;align-items:center;gap:8px; }
/* B40 C48 — covered participant: Pays locked */
.wl-tog-lock{ opacity:.55;cursor:not-allowed; }
/* B40 C54 — Balance per-user net boxes */
.wl-user{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff);overflow:hidden; }
.wl-user + .wl-user{ margin-top:8px; }
.wl-user .wl-user-h{ border:0;border-radius:0; }
.wl-user-caret .mi{ transition:transform var(--mk-t-fast); }
.wl-user-caret.open .mi{ transform:rotate(180deg); }
.wl-user-txns{ border-top:1px solid var(--bd-1,#dfe4e8);background:var(--bg-2,#f7f9fa);padding:6px 12px 8px; }
.wl-txn{ display:flex;align-items:center;gap:9px;padding:7px 2px;min-width:0;flex-wrap:wrap; }
.wl-txn + .wl-txn{ border-top:1px dashed color-mix(in srgb,var(--bd-1,#dfe4e8) 70%,transparent); }
.wl-txn-src{ flex:1;min-width:120px;font:600 12px/1.3 var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer; }
.wl-txn-src:hover{ color:var(--accent-text,var(--accent)); }
.wl-txn-acts{ display:flex;gap:5px;flex:0 0 auto;align-items:center; }
.wl-txn-panel{ padding:9px 4px; }
.wl-debt-state.warn{ color:var(--mk-warning,#F59E0B); }
/* B40 C56 — banner + pending numbers on Balance */
.wl-banner{ margin-bottom:14px; }
.bb-pend{ display:flex;align-items:center;gap:5px;font:600 11px/1.2 var(--mk-font-ui);color:rgba(255,255,255,.75);margin-top:4px; }
.bb-pend .mi{ font-size:13px; }
.bb-pend.pos{ color:#7BE8C4; } .bb-pend.neg{ color:#FFB3A8; }
/* B45 C1 — pending: icon+value on one row, description on its OWN full-width
   line below (no weird wrap next to the icon). */
.bb-pend{ display:flex;flex-direction:column;align-items:flex-start;gap:1px; }
.bb-pend-top{ display:flex;align-items:center;gap:5px; }
.bb-pend-top .mi{ font-size:13px;margin-top:0; }
.bb-pend-v{ font:800 12.5px/1.15 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.bb-pend-l{ font:600 10px/1.3 var(--mk-font-ui);opacity:.82;text-wrap:pretty;width:100%; }
/* B43 C6 — payment-method cards (logos + progress).
   B46 C01 chose auto-FIT so a short group would STRETCH to fill the row instead of
   leaving desktop space empty. B57 REVERSES that on Pablo's later comment ("I don't
   know why you're making the cards for credit cards have less width than the other
   accounts"): stretching is exactly what made a one-card group 4× the width of a
   card in a four-card group, and with every account now grouped on ONE screen the
   inequality reads as a bug. auto-FILL keeps the tracks, so all cards match. */
.wl-pm-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:10px; }
.wl-pmc{ display:flex;flex-direction:column;gap:9px;padding:13px 14px;border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff); }
.wl-pmc.wl-click{ cursor:pointer;transition:border-color .15s,box-shadow .15s; }
.wl-pmc.wl-click:hover{ border-color:var(--accent);box-shadow:0 3px 12px color-mix(in srgb,var(--accent) 12%,transparent); }
.wl-pmc-top{ display:flex;align-items:flex-start;gap:10px; }
/* B59 — the expiration chip is absolutely positioned against the CARD (see
   `.wl-pmc-exp`), so the card owns the containing block and the top row reserves a
   gutter for it instead of surrendering title width. The gutter is only applied when
   a chip is actually present, so a chipless card keeps the full row. */
.wl-pmc{ position:relative; }
/* The chip is emitted INSIDE `.wl-pmc-top` (see `wlPmCard`), so the gutter is asked
   of the row that contains it. Written as `.wl-pmc:has(> .wl-pmc-exp)` first, which
   matched nothing and read as a working rule: `padding-inline-end` computed to 0px,
   the chip's box sat over the name and type boxes, and — because the chip is out of
   flow — NOTHING was clipped, so only a box-overlap assertion caught it. A `:has`
   whose subject is the wrong ancestor fails silently; measure the computed value. */
/* The gutter is sized to a COMPACT chip, and the title wraps beneath it. 86px was
   the first attempt and it simply moved the clipping: a 245px card in the 3-column
   grid has ~215px of row, so logo (40) + gap (10) + gutter (86) left the title 79px
   and "Davibank Mastercard" clipped again. The chip is now icon + `MM/YY` (~58px),
   and both title lines may take two lines, so the text has somewhere to go instead
   of somewhere to be cut. */
/* B61 - the corner slot holds the CURRENCY chip on every account card; the
   expiration moved into the chip row. Same out-of-flow trick, same gutter logic. */
.wl-pmc-cur{ position:absolute;top:14px;inset-inline-end:14px;z-index:1;flex:0 0 auto; }
.wl-pmc-top:has(> .wl-pmc-cur){ padding-inline-end:78px; }
.wl-chip-exp{ font-variant-numeric:tabular-nums; }
.wl-chip-exp.soon{ background:color-mix(in srgb,var(--mk-warning,#c98a12) 15%,var(--bg-1,#fff));
  color:color-mix(in srgb,var(--mk-warning,#c98a12) 80%,var(--fg-1)); }
.wl-chip-exp.soon .mi{ color:inherit; }
/* `:has` is well supported, but the fallback matters: without the gutter the chip
   overlaps the title rather than merely crowding it. */
@supports not selector(:has(*)){ .wl-pmc-top{ padding-inline-end:86px; } }
/* B50-18 (Pablo: "I'd rather see this cropped in the rounded square shape rather
   than seeing a square image with a white edge") — the tile used to letterbox a
   `contain` image over a white plate with padding. It now CROPS: the artwork
   fills the rounded square edge-to-edge, no plate, no inset ring. */
/* B55 (Pablo: "I still see a square going out of a circle. The idea is to crop
   the image in a circular shape not paste the square image inside a circle-shaped
   div" + "The mastercard logo is cropped which is fine but we should crop to the
   largest side (height or width) so that the content fits within the crop") —
   two separate demands, both honoured here:

   • a REAL circular crop: `clip-path:circle(50%)` on the mark clips the raster
     itself, not just the box. `overflow:hidden` + `border-radius` alone is what
     let a square edge show through (any child paint that establishes its own
     layer escapes a rounded box; it cannot escape a clip-path).
   • scaled by the LARGEST side, so nothing of the artwork is lost: that is
     `object-fit:contain`, with the circle clipping only the empty corners. A
     `cover` fit is what was slicing the Mastercard wordmark.

   `.wl-pmc-mk` is the one mark used by BOTH the payment card and the account
   panel header — B55 found those had drifted apart (the header still emitted the
   a badge class this file no longer defines), so there is one class now. */
.wl-pmc-logo{ position:relative;width:40px;height:40px;flex:0 0 auto }
.wl-pmc-mk{ width:40px;height:40px;flex:0 0 auto;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:#fff;clip-path:circle(50%);
  box-shadow:inset 0 0 0 1px var(--bd-1,var(--border)) }
.wl-pmc-mk.lg{ width:52px;height:52px }
.wl-pmc-mk.sm{ width:26px;height:26px }
.wl-pmc-mk.is-fb{ background:var(--bg-2,#eef1f4) }
.wl-pmc-mk > .wl-logo{ width:100%;height:100%;border-radius:50%;overflow:hidden }
/* the plate keeps a hair of padding so a wordmark never touches the ring */
.wl-pmc-mk.is-bank > .wl-logo{ padding:4px }
.wl-pmc-mk.sm.is-bank > .wl-logo{ padding:2px }
.wl-pmc-mk > .wl-logo > img{ width:100%;height:100%;object-fit:contain;display:block;border-radius:inherit }
.wl-logo{ display:inline-flex;align-items:center;justify-content:center;overflow:hidden }
.wl-logo img{ width:100%;height:100%;object-fit:contain;display:block }
.wl-pmc-fb{ color:var(--fg-3);font-size:20px }
/* B55 — the account panel's header is the same mark family, laid out as a row */
.wl-acct-logo-hd{ display:flex;align-items:center;gap:9px;margin-bottom:4px }
.wl-pmc-id{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px; }
.wl-pmc-nm{ font:700 13.5px/1.2 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.wl-pmc-ty{ font:500 11px/1.2 var(--mk-font-ui);color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
/* B59 — the title lines WRAP beside the expiration chip instead of truncating.
   Placed deliberately AFTER the two `white-space:nowrap` declarations above: this
   rule first sat ~40 lines earlier in the file at equal specificity, so the nowrap
   won the cascade and three names still clipped at the 3-column width while every
   other assertion passed. Same trap as the `:has` subject — the rule existed and
   did nothing. Two lines, then ellipsis, so a pathological string still cannot grow
   the card. */
.wl-pmc-nm, .wl-pmc-ty{ white-space:normal;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden;text-overflow:clip;overflow-wrap:anywhere; }
.wl-pmc-flag{ flex:0 0 auto;display:inline-flex; }
/* B54 — "the bank logos and the country flags seem too big": the flag is a
   supporting detail on the card, so it drops to a 17px circle. */
.wl-pmc-flag .wl-flag{ width:17px;height:17px; }
/* B55 — the network is the primary mark and the BANK now sits immediately before
   the flag (`.wl-pmc-mk.is-bank.sm`), which is what Pablo asked for: "the bank
   logo would show up to the left of the country flag, not as a corner tag to the
   card scheme logo". The earlier badge/main/sub classes are all gone; everything
   is `.wl-pmc-mk`. */
.wl-pmc-bal{ display:flex;align-items:baseline;gap:8px;flex-wrap:wrap; }
.wl-pmc-bal-v{ font:800 19px/1.05 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-pmc-bal-v.neg{ color:var(--mk-danger,#d64545); }
.wl-pmc-mask{ font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.06em; }
.wl-pmc-bal-conv{ font:500 11.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums;margin-inline-start:auto; }
.wl-pmc-prog{ display:flex;flex-direction:column;gap:8px; }
.wl-pmc-bar{ position:relative;height:6px;border-radius:999px;background:var(--bg-2,#eef1f4);overflow:hidden; }
.wl-pmc-bar span{ position:relative;display:block;height:100%;border-radius:999px;background:var(--accent); }
.wl-pmc-bar.hot span{ background:var(--mk-danger,#d64545); }
.wl-pmc-bar.loan span{ background:var(--mk-ok,#2f9e63); }
.wl-pmc-prog-l{ display:flex;justify-content:space-between;gap:4px 8px;flex-wrap:wrap;font:600 10.5px/1.2 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.wl-pmc-prog-l > span{ min-width:0; }
.wl-pmc-prog-l.split .pos{ color:var(--mk-ok,#2f9e63); } .wl-pmc-prog-l.split .neg{ color:var(--mk-danger,#d64545); }
/* ══ B57 — accounts inside Balance ══════════════════════════════════
   Pablo: "I don't know why you're making the cards for credit cards have less width
   than the other accounts" — TWO causes, both measured: the `:only-child` rule that
   widened a one-card group to 520px, and `auto-FIT`, which collapses a short group's
   empty tracks and hands their space to the survivors — so the one-card Savings-fund
   group spanned 998px while each of the four Cards sat at 242px. `auto-FILL` keeps
   the tracks, so every account card in every group is exactly one column wide. */
/* the bank + currency chips under the title (the title is the NICKNAME now) */
.wl-pmc-chips{ display:flex;flex-wrap:wrap;gap:6px; }
.wl-pmc-chips .wl-chip{ padding:4px 9px;font-size:11px; }
.wl-chip-mk{ padding-inline-start:4px; }
.wl-pmc-mk.xs{ width:20px;height:20px; }
.wl-pmc-mk.xs.is-bank > .wl-logo{ padding:1px; }
.wl-chip .wl-flag{ width:16px;height:16px;border-radius:50%;overflow:hidden;display:inline-flex; }
.wl-sech-sum{ margin-inline-start:auto;font:700 12px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wl-pmc-linked{ display:flex;align-items:center;gap:5px;font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-3); }
.wl-pmc-linked .mi{ font-size:14px; }
/* the interest INSIDE what you owe — a segment at the leading edge of the used
   part on a card, and the not-yet-paid tail on a loan's track. */
.wl-bar-int{ position:absolute;inset-inline-end:0;top:0;bottom:0;background:var(--mk-danger,#d64545);opacity:.6;border-radius:inherit; }
.wl-bar-int-tail{ position:absolute;inset-inline-end:0;top:0;bottom:0;background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--mk-danger,#d64545) 45%,transparent) 0 3px,transparent 3px 6px); }
.wl-pmc-prog-l.int{ font-weight:600;color:var(--fg-3); }
.wl-pmc-prog-l.int span{ display:inline-flex;align-items:center;gap:4px; }
.wl-int-key{ width:8px;height:8px;border-radius:2px;background:var(--mk-danger,#d64545);opacity:.7;flex:0 0 auto; }
.wl-int-key.fund{ background:var(--mk-ok,#2f9e63);opacity:.85; }
.wl-pmc-bar.fund span{ background:var(--mk-ok,#2f9e63); }
/* ══ B59 — WHAT A CARD SAYS ABOUT ITS MONEY ═══════════════════════════
   Pablo, on the credit card: "I think the interest can live on a chip, the amount
   used and interest could be marked with lines in the bar or something. I need more
   visual elements. The expiration of the card could even be a chip that lives at the
   top right". And on the loan: "I prefer small claims or numbers with color coded
   tags and icons maybe. A bunch of text in the same font feels cheap".
   So: a MARKED bar + a row of stat chips, and no run of same-size label text. The
   `.wl-pmc-bar` / `.wl-pmc-prog-l` / `.wl-bar-int*` / `.wl-int-key` set above is kept
   only because the ACCOUNT PANEL's plan summary still draws a plain track; the CARDS
   on Balance use `.wl-pmcb` + `.wl-stats` exclusively. */
.wl-pmcb{ position:relative;height:9px;border-radius:999px;background:var(--bg-2,#eef1f4);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg-1) 6%,transparent) }
.wl-pmcb-f{ position:absolute;inset-block:0;inset-inline-start:0;border-radius:999px;background:var(--accent);transition:width .28s cubic-bezier(.4,0,.2,1) }
.wl-pmcb.hot > .wl-pmcb-f{ background:var(--mk-danger,#d64545) }
.wl-pmcb.loan > .wl-pmcb-f, .wl-pmcb.fund > .wl-pmcb-f{ background:var(--mk-ok,#2f9e63) }
/* the hatched run — Pablo liked the barbershop fill but could not tell what it
   meant ("I like this barbershop bar but I'm not sure what it means, it would be nice
   to see some other informative visual element"), so the same hatch is now the KEY of
   the stat chip that names it. */
/* B62 W-76 ("Why don't we just do a solid orange color?", on `.loan > .wl-pmcb-h`) —
   the interest run is SOLID now, in the app's own warning token, which is also the
   colour its "Interest to come" / "Interest inside" stat already speaks in. The hatch
   survives only where it still carries meaning: a fund's yield, whose fill is the same
   green, so a solid block there would vanish into it. */
.wl-pmcb-h{ position:absolute;inset-block:0;
  background:var(--mk-warning,#c98a12) }
.wl-pmcb-h.fund{ background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--mk-ok,#2f9e63) 62%,transparent) 0 3px,transparent 3px 6px) }
/* "marked with lines in the bar" — a hairline tick at each boundary. */
.wl-pmcb-k{ position:absolute;inset-block:-1px;width:2px;border-radius:1px;background:var(--bg-1,#fff);
  box-shadow:0 0 0 .5px color-mix(in srgb,var(--fg-1) 22%,transparent) }
/* B61 (Pablo: "Too many boxes too big of a font and very difficult to read. I want
   simplicity and visual elements. The progress bar looks nice though.") - the stats
   are a LEGEND of the bar above them, not three tiles: mark, number, label, one
   line each, no tint, no stack. The bar keeps everything it had. */
.wl-stats{ display:flex;flex-wrap:wrap;gap:3px 14px;align-items:center;margin-top:2px }
.wl-stat{ display:inline-flex;align-items:baseline;gap:5px;min-width:0;padding:0;
  background:none;box-shadow:none;font-variant-numeric:tabular-nums }
.wl-stat > .mi{ font-size:13px;color:var(--fg-3);flex:0 0 auto;align-self:center }
.wl-stat b{ font:700 11.5px/1.4 var(--mk-font-ui);color:var(--fg-1);white-space:nowrap }
.wl-stat em{ font:600 10px/1.4 var(--mk-font-ui);font-style:normal;color:var(--fg-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0 }
.wl-stat.ok > .mi, .wl-stat.ok b{ color:var(--mk-ok,#2f9e63) }
.wl-stat.bad > .mi, .wl-stat.bad b{ color:var(--mk-danger,#d64545) }
.wl-stat.warn > .mi, .wl-stat.warn b{ color:color-mix(in srgb,var(--mk-warning,#c98a12) 78%,var(--fg-1)) }
/* the swatch form of a stat's mark: the bar segment it stands for, verbatim.
   B62 W-77 ("This particular legend seems to be missaligned") — measured: the swatch
   sat 2.5px BELOW the number it labels, because `.wl-stat` aligns on the BASELINE and a
   13px box has none, while the glyph marks beside it are pulled to centre. Same rule,
   same result: Δ 0.0px. W-76 makes the interest swatch solid, so the legend still reads
   as the segment it names. */
.wl-sw{ width:13px;height:13px;border-radius:4px;flex:0 0 auto;align-self:center;
  background:var(--mk-warning,#c98a12);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg-1) 10%,transparent) }
.wl-sw.fund{ background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--mk-ok,#2f9e63) 70%,transparent) 0 3px,transparent 3px 6px) }
/* the ONE top-trailing chip: a card's printed expiry, a loan's last projected
   instalment, a fund's maturity. `soon` (inside a quarter) is the only alarm.

   It is POSITIONED, not a flex sibling — and that is the whole point. As a third
   child of `.wl-pmc-top` it was `flex:0 0 auto` at ~75px, which on a 245px card in
   the 3-column grid left the title block only ~80px and ellipsized the very strings
   B59 exists to state: "Carlos Rueda L…", "Davibank Mastercar…", "Retirement 20…".
   Four of the six chip-bearing cards were clipped; the five without a chip were not.
   Pablo asked for a chip that "lives at the top right section of the card" — living
   there is a position, not a claim on the title's width. Out of flow, the title block
   gets the full row back and `.wl-pmc-top` reserves just the gutter the chip needs. */
.wl-pmc-exp{ position:absolute;top:14px;inset-inline-end:14px;z-index:1;
  display:inline-flex;align-items:center;gap:3px;
  padding:3px 7px 3px 5px;border-radius:999px;background:var(--bg-2,#f1f4f7);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg-1) 8%,transparent);
  font:700 10.5px/1.35 var(--mk-font-ui);color:var(--fg-2);white-space:nowrap;font-variant-numeric:tabular-nums }
.wl-pmc-exp > .mi{ font-size:12px;color:var(--fg-3) }
.wl-pmc-exp.soon{ background:color-mix(in srgb,var(--mk-warning,#c98a12) 15%,var(--bg-1,#fff));color:color-mix(in srgb,var(--mk-warning,#c98a12) 80%,var(--fg-1)) }
.wl-pmc-exp.soon > .mi{ color:inherit }
/* B59 — a loan's counterparty as the card's thumbnail ("show the person's avatar as
   the main thumbnail of the card and the name concatenated with the account type"). */
.wl-pmc-mk.is-person{ background:transparent;box-shadow:none }
.wl-pmc-mk.is-person > .wl-av{ width:100%;height:100%;font-size:15px }
.wl-pmc-mk.is-person.lg > .wl-av{ font-size:19px }
/* ── B59 — a Balance section is a fold with a signed net ─────────────
   Pablo: "Each section should have the net total with color codes (green for
   positive and red for negatives) as well as allowing me to collapse". */
.wl-sech-c{ cursor:pointer;user-select:none;border-radius:9px;margin-inline:-6px;padding:4px 6px;
  transition:background .16s ease }
.wl-sech-c:hover{ background:var(--bg-2,#f1f4f7) }
.wl-sech-c:focus-visible{ outline:2px solid var(--accent);outline-offset:1px }
.wl-sech-car{ transition:transform .2s cubic-bezier(.4,0,.2,1) }
.wl-sech-c.open .wl-sech-car{ transform:rotate(90deg) }
[dir="rtl"] .wl-sech-car{ transform:rotate(180deg) }
[dir="rtl"] .wl-sech-c.open .wl-sech-car{ transform:rotate(90deg) }
.wl-sech-sum.pos{ color:var(--mk-ok,#2f9e63) }
.wl-sech-sum.neg{ color:var(--mk-danger,#d64545) }
.wl-sech-b[hidden]{ display:none }
/* the loan payment plan + the fund promise (panel view) */
.wl-plan-sum{ display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:8px;margin-bottom:10px; }
.wl-plan-cell{ border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;padding:9px 11px;background:var(--bg-1,#fff);min-width:0; }
.wl-plan-l{ display:block;font:700 9.5px/1.2 var(--mk-font-ui);letter-spacing:.07em;text-transform:uppercase;color:var(--fg-3); }
.wl-plan-v{ display:block;margin-top:4px;font:700 14px/1.1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-plan-v.int{ color:var(--mk-danger,#d64545); } .wl-plan-v.fund{ color:var(--mk-ok,#2f9e63); }
.wl-plan{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;overflow:hidden;background:var(--bg-1,#fff); }
.wl-plan-row{ display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 12px; }
.wl-plan-row + .wl-plan-row{ border-top:1px solid var(--bd-1,#dfe4e8); }
.wl-plan-d{ min-width:58px;font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.wl-plan-a{ font:700 12.5px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-plan-split{ margin-inline-start:auto;display:flex;align-items:center;gap:9px;font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.wl-plan-key{ width:7px;height:7px;border-radius:2px;background:var(--mk-ok,#2f9e63);margin-inline-end:-4px; }
.wl-plan-key.int{ background:var(--mk-danger,#d64545);margin-inline-start:4px; }
.wl-plan-note{ display:flex;align-items:center;gap:6px;margin:7px 0 0;font:500 11px/1.35 var(--mk-font-ui);color:var(--fg-3); }
.wl-plan-note .mi{ font-size:14px; }
/* a fact the form INHERITS rather than asks for (the debit-card slide) */
.wl-note-row{ display:flex;align-items:center;gap:7px;padding:9px 11px;border-radius:10px;background:var(--bg-2,#eef1f4);font:500 12px/1.35 var(--mk-font-ui);color:var(--fg-2);flex-wrap:wrap; }
/* B60 - the key/value rows of the debt-source slide (what it is, when, how much,
   who): a statement, not a form, so no field chrome. */
.wl-kv{ display:flex;align-items:baseline;gap:12px;padding:8px 2px;border-bottom:1px solid var(--divider,var(--bd-1,#dfe4e8)); }
.wl-kv:last-of-type{ border-bottom:0; }
.wl-kv-k{ flex:0 0 34%;font:600 11.5px/1.4 var(--mk-font-ui);color:var(--fg-3); }
.wl-kv-v{ flex:1 1 auto;min-width:0;font:600 12.5px/1.4 var(--mk-font-ui);color:var(--fg-1);
  font-variant-numeric:tabular-nums;display:flex;align-items:center;gap:6px;flex-wrap:wrap; }
.wl-txn-panel.wl-click{ cursor:pointer;border-radius:10px;transition:background var(--mk-t-fast); }
.wl-txn-panel.wl-click:hover{ background:color-mix(in srgb,var(--accent) 7%,transparent); }
.wl-note-row .mi{ font-size:15px;color:var(--fg-3); }
.wl-req-mark{ color:var(--mk-danger,#d64545);font-style:normal;font-weight:700; }
.wl-cs.wl-req .cs-btn{ border-color:var(--mk-danger,#d64545); }
.wl-add[disabled]{ opacity:.45;cursor:not-allowed; }
.wl-add[disabled]:hover{ border-color:var(--bd-1,#dfe4e8);color:inherit; }
/* a dropdown option's subordinate key (currency ticker beside its name) */
.cs-opt-sub{ margin-inline-start:auto;font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.05em;flex:0 0 auto; }
.wl-cs .cs-item .wl-flag,.wl-cs .cs-val .wl-flag{ width:18px;height:18px;border-radius:50%;overflow:hidden;flex:0 0 auto; }
.wl-pmc-people .wl-pmc-go{ color:var(--fg-3);font-size:20px;margin-inline-start:auto; }
.wl-pmc-people-avs{ display:inline-flex;align-items:center;margin-inline-start:auto; }
.wl-pmc-people-avs .wl-av{ margin-inline-start:-6px;box-shadow:0 0 0 2px var(--bg-1,#fff); }
.wl-pmc-more{ font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);margin-inline-start:4px; }
/* B55 — the stale `.wl-acct-logo-hd .wl-logo.lg` block that used to live here
   (48px, 11px radius, `object-fit:cover`) is gone: it was a SECOND, squarer
   treatment of the same mark and it fought the circular one, which is half of why
   Pablo called this header broken. The header uses `.wl-pmc-mk.lg` now. */
/* B40 C39 — overlap chips + place-picker modal */
.wl-overlap{ display:inline-flex;align-items:center;gap:4px;margin-top:3px;padding:2px 8px;border-radius:999px;background:color-mix(in srgb,var(--accent) 10%,transparent);font:600 10.5px/1.4 var(--mk-font-ui);color:var(--accent-text,var(--accent));width:max-content;max-width:100%; }
.wl-overlap .mi{ font-size:12px; }
.wl-overlaps{ display:flex;flex-wrap:wrap;gap:5px;margin-top:-4px; }
.wl-modal-scrim{ position:fixed;inset:0;z-index:1400;background:rgba(13,25,32,.45);display:none;align-items:center;justify-content:center;padding:18px; }
.wl-modal-scrim.open{ display:flex; }
.wl-modal{ width:min(720px,100%);max-height:min(84dvh,680px);display:flex;flex-direction:column;background:var(--bg-1,#fff);border:1px solid var(--bd-1,#dfe4e8);border-radius:16px;box-shadow:0 24px 70px rgba(13,25,32,.28);overflow:hidden; }
.wl-modal-hd{ display:flex;align-items:center;gap:9px;padding:12px 14px;border-bottom:1px solid var(--bd-1,#dfe4e8); }
.wl-modal-hd > .mi{ color:var(--accent-text,var(--accent));font-size:19px; }
.wl-modal-hd b{ font:700 14px/1 var(--mk-font-ui);color:var(--fg-1); }
.wl-place-seg{ margin-inline-start:auto;display:flex;gap:2px;flex-wrap:wrap; }
.wl-place-seg button{ border:0;background:none;padding:6px 10px;border-radius:999px;font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2);cursor:pointer; }
.wl-place-seg button.on{ background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text,var(--accent)); }
/* B63-055 — one-tap quick picks (e.g. a trip's own destinations) above the
   place picker's drill-down map. */
.wl-place-quick{ display:flex;flex-wrap:wrap;gap:6px;padding:9px 14px 0; }
.wl-place-crumbs{ display:flex;flex-wrap:wrap;gap:6px;align-items:center;padding:9px 14px;border-bottom:1px solid var(--bd-1,#dfe4e8);min-height:22px; }
.wl-place-map{ flex:1;min-height:300px; }
.wl-modal-ft{ display:flex;align-items:center;gap:8px;justify-content:flex-end;padding:10px 14px;border-top:1px solid var(--bd-1,#dfe4e8); }
.wl-place-sel{ margin-inline-end:auto;font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0; }
/* B40 C29 — buraco basket groups + − n + steppers */
.bu-group{ border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;background:var(--bg-1,#fff);overflow:hidden; }
.bu-group + .bu-group{ margin-top:6px; }
.bu-group-h{ display:flex;align-items:center;gap:7px;padding:8px 11px;cursor:pointer;font:600 12.5px/1 var(--mk-font-ui);color:var(--fg-1); }
.bu-group-h .bu-caret{ font-size:17px;color:var(--fg-3);transition:transform var(--mk-t-fast); }
.bu-group.open .bu-group-h .bu-caret{ transform:rotate(90deg); }
[dir="rtl"] .bu-group.open .bu-group-h .bu-caret{ transform:rotate(-90deg); }
.bu-group-cnt{ margin-inline-start:auto;font:800 11px/1 var(--mk-font-ui);color:var(--accent-text,var(--accent));background:color-mix(in srgb,var(--accent) 11%,transparent);padding:3px 8px;border-radius:999px; }
.bu-group-b{ border-top:1px solid var(--bd-1,#dfe4e8);padding:4px 11px 8px; }
.bu-group-b[hidden]{ display:none; }
.bu-var{ display:flex;align-items:center;gap:8px;padding:6px 0; }
.bu-var + .bu-var{ border-top:1px dashed color-mix(in srgb,var(--bd-1,#dfe4e8) 70%,transparent); }
.bu-var-nm{ flex:1;min-width:0;font:600 12px/1.2 var(--mk-font-ui);color:var(--fg-2); }
.bu-var-v{ font:700 11px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.bu-var-v.pos{ color:var(--mk-ok,#2f9e63); } .bu-var-v.neg{ color:var(--mk-danger,#d64545); }
.bu-step{ display:inline-flex;align-items:center;gap:2px;border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;padding:2px; }
.bu-step-b{ width:22px;height:22px;border:0;border-radius:50%;background:var(--bg-2,#f4f6f8);display:grid;place-items:center;cursor:pointer;color:var(--fg-2);padding:0; }
.bu-step-b:hover{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent-text,var(--accent)); }
.bu-step-b:disabled{ opacity:.4;cursor:default; }
.bu-step-b .mi{ font-size:14px; }
.bu-step-n{ min-width:20px;text-align:center;font:800 12px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.bu-sec-b .ent-toggle{ margin-top:8px; }
.wl-fee-ed{ display:flex;align-items:center;gap:7px; }
.wl-fee-ed select{ flex:1;min-width:0; } .wl-fee-ed input.num{ width:88px;flex:0 0 auto; }
.wl-amtpct{ display:inline-flex;border:1px solid var(--bd-1,#dfe4e8);border-radius:8px;overflow:hidden;flex:0 0 auto; }
.wl-amtpct button{ border:0;background:transparent;font:700 11px/1 var(--mk-font-ui);color:var(--fg-3);padding:7px 9px;cursor:pointer; }
.wl-amtpct button.on{ background:color-mix(in srgb, var(--accent) 12%, transparent);color:var(--accent); }
.wl-fee-payers{ display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin:-2px 0 6px; }
.wl-ppick{ border:1px solid var(--bd-1,#dfe4e8);border-radius:999px;background:transparent;padding:4px 10px;font:600 11px/1 var(--mk-font-ui);color:var(--fg-3);cursor:pointer; }
.wl-ppick.on{ border-color:var(--accent);color:var(--accent);background:color-mix(in srgb, var(--accent) 9%, transparent); }
.wl-x{ border:0;background:transparent;color:var(--fg-3);cursor:pointer;padding:4px;border-radius:7px;flex:0 0 auto; }
.wl-x:hover{ color:var(--mk-danger,#d64545);background:color-mix(in srgb, var(--mk-danger,#d64545) 9%, transparent); }
.wl-x .mi{ font-size:17px; }
.wl-add{ display:inline-flex;align-items:center;gap:6px;align-self:flex-start;border:1px dashed var(--bd-1,#dfe4e8);border-radius:9px;background:transparent;padding:7px 12px;font:600 12px/1 var(--mk-font-ui);color:var(--fg-2);cursor:pointer; }
.wl-add:hover{ border-color:var(--accent);color:var(--accent); }
.wl-add.sm{ padding:5px 10px;font-size:11.5px; }
.wl-add .mi{ font-size:16px; }
/* B40 C41 — people read as VERTICAL rows ("stick to what we know"). */
.wl-people{ display:flex;flex-direction:column;gap:6px; }
.wl-person{ display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:11px;border:1px solid var(--bd-1,#dfe4e8);background:var(--bg-1,#fff);font:600 12px/1 var(--mk-font-ui);color:var(--fg-1); }
.wl-owner{ font:700 9.5px/1 var(--mk-font-ui);color:var(--accent);text-transform:none;letter-spacing:.05em; }
.wl-dish{ display:flex;flex-direction:column;gap:3px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;margin-bottom:7px;background:var(--bg-1,#fff); }
.wl-dish-nm{ font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-dish-rec{ font:500 11.5px/1.4 var(--mk-font-ui);color:var(--fg-3); }
.wl-trav{ display:flex;align-items:center;gap:9px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;margin-bottom:7px;background:var(--bg-1,#fff);font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-trav .mi{ font-size:17px;color:var(--accent); }
.wl-hint{ margin:0 0 10px;font:500 12px/1.5 var(--mk-font-ui);color:var(--fg-3); }
.wl-close-btn{ display:inline-flex;align-items:center;gap:7px;padding:10px 18px;border-radius:10px;border:0;background:var(--accent);color:#fff;font:700 13px/1 var(--mk-font-ui);cursor:pointer; }
.wl-close-btn:hover{ filter:brightness(1.06); }
/* B55 — lives with the button, not in contacts.css: the panel footer's primary
   action is shared, and the games disable it while nothing matches. */
.wl-close-btn[disabled]{ opacity:.5;cursor:not-allowed;filter:none; }
.wl-close-btn[disabled]:hover{ filter:none; }
.wl-close-btn .mi{ font-size:17px; }
.wl-settled{ display:flex;align-items:center;gap:7px;font:600 12.5px/1.3 var(--mk-font-ui);color:var(--mk-ok,#2f9e63);margin-bottom:9px; }

/* ── B39 C39 — Ledger: kinds, payments log, recipients ── */
.wl-kind-chip .mi{ color:var(--accent); }
.wl-kic{ font-size:19px; }
.wl-kic-earning,.wl-kic-credit,.wl-kic-refund{ color:var(--mk-ok,#2f9e63) !important; }
.wl-kic-transfer{ color:var(--fg-2) !important; }
.wl-kic-fee,.wl-kic-purchase{ color:var(--accent) !important; }
.wl-flow-in{ color:var(--mk-ok,#2f9e63) !important; } .wl-flow-out{ color:var(--fg-1); }
.wl-pms{ display:flex;flex-direction:column;gap:6px;margin-bottom:8px; }
.wl-pm{ display:flex;align-items:center;gap:9px;padding:8px 11px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff); }
.wl-pm-main{ display:flex;flex-direction:column;gap:2px;flex:1;min-width:0; }
.wl-pm-who{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-pm-acct{ font:500 11px/1.2 var(--mk-font-ui);color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.wl-pm .wl-amt{ margin-inline-start:auto;font-variant-numeric:tabular-nums; }
.wl-warn{ color:var(--mk-danger,#d64545) !important; }
.wl-recip-ov{ display:inline-flex;align-items:center;gap:4px;margin-inline-start:8px;padding:2px 8px;border-radius:999px;background:color-mix(in srgb, var(--accent) 10%, transparent);font:600 10.5px/1 var(--mk-font-ui);color:var(--accent); }
.wl-recip-ov .mi{ font-size:13px; }
.wl-pay-ed{ display:flex;align-items:center;gap:7px;flex-wrap:wrap; }
.wl-pay-ed select[data-pm="payer"]{ flex:1 1 120px;min-width:0; } .wl-pay-ed select[data-pm="account"]{ flex:1 1 130px;min-width:0; }
.wl-pay-ed input.num{ width:92px;flex:0 0 auto; } .wl-pay-ed input[type="date"]{ flex:0 0 auto;width:132px; }
.wl-pay-alloc{ display:flex;align-items:center;gap:6px;font:600 11.5px/1.3 var(--mk-font-ui);margin:2px 0 4px; }
.wl-pay-alloc[hidden]{ display:none; }
/* B62 W-71 — covered says nothing; a shortfall is an ERROR (it blocks the save), so it
   wears the danger tone on a tinted field instead of a bare warning line. */
.wl-pay-alloc.bad{ color:var(--mk-danger,#d64545);background:color-mix(in srgb,var(--mk-danger,#d64545) 9%,transparent);
  border-radius:9px;padding:7px 10px; }
.wl-alloc-flash{ animation:wlAllocFlash .9s ease-out 1; }
@keyframes wlAllocFlash{ 0%,100%{ box-shadow:0 0 0 0 transparent } 30%{ box-shadow:0 0 0 3px color-mix(in srgb,var(--mk-danger,#d64545) 30%,transparent) } }
.wl-pay-alloc .mi{ font-size:15px; } .wl-pay-alloc.ok{ color:var(--mk-ok,#2f9e63); } .wl-pay-alloc.warn{ color:var(--mk-danger,#d64545); }
.wl-mini-btn{ border:1px solid currentColor;background:transparent;color:inherit;border-radius:999px;padding:2px 9px;font:600 10.5px/1 var(--mk-font-ui);cursor:pointer;margin-inline-start:4px; }
.wl-mini-btn:hover{ background:color-mix(in srgb, currentColor 12%, transparent); }
.wl-recip-ovrow{ display:flex;align-items:center;gap:8px;flex:1 1 100%; }
.wl-mini-l{ display:inline-flex;align-items:center;gap:4px;font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3);white-space:nowrap; }
.wl-mini-l .mi{ font-size:14px; }
.wl-recip-ovrow .wl-recip-sel{ flex:1;min-width:0; }
/* C2 — 2-part recipient control (type + dependent entries dropdown) */
.wl-recip2{ display:flex;gap:6px;flex:1;min-width:0;align-items:stretch; }
.wl-recip2 > .wl-cs{ flex:1 1 0;min-width:0; }
.wl-recip-idwrap{ flex:1 1 0;min-width:0;display:flex; }
.wl-recip-idwrap .wl-cs{ width:100%; }
.wl-recip2.no-type .wl-recip-idwrap{ display:none; }
.wl-recip-ovrow .wl-recip2{ flex:1;min-width:0; }

/* ── B39 C30 — Accounts view / editor ── */
.wl-acct-idn{ display:inline-flex;align-items:center;gap:3px;margin-inline-start:8px;color:var(--fg-3);font-weight:700; } .wl-acct-idn .mi{ font-size:13px; }
.wl-acct-bal{ display:flex;flex-direction:column;gap:2px;padding:14px 16px;border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff);margin-bottom:4px; }
.wl-acct-bal-l{ font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.02em; }
.wl-acct-bal-v{ font:800 26px/1.1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-acct-bal-conv{ font:600 11.5px/1.3 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums; }
.wl-pid{ display:flex;align-items:center;gap:11px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);margin-bottom:6px; }
.wl-pid-ic{ font-size:19px;color:var(--accent);flex:0 0 auto; }
.wl-pid-main{ display:flex;flex-direction:column;gap:2px;min-width:0; }
.wl-pid-k{ font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.02em; }
.wl-pid-v{ font:600 13px/1.3 var(--mk-font-ui);color:var(--fg-1);word-break:break-all; }
.wl-pid-ed{ display:flex;flex-direction:column;gap:7px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;padding:10px 12px;background:var(--bg-1,#fff);margin-bottom:7px; }
.wl-pid-ed-h{ display:flex;align-items:center;gap:8px; } .wl-pid-ed-h select{ flex:1;min-width:0; }

/* ── B39 C35 — Trip schedule / menus / derived groceries ── */
.wl-frow-inline{ display:flex;align-items:center;gap:8px; } .wl-frow-inline .ent-input{ flex:1;min-width:0; } .wl-frow-inline input[type="date"]{ flex:0 0 auto; }
.wl-meal{ display:flex;flex-direction:column;gap:6px;padding:10px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff);margin-bottom:7px; }
.wl-meal-h{ display:flex;align-items:center;gap:8px;flex-wrap:wrap; }
.wl-meal-date{ font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wl-meal-kind{ font:600 12.5px/1 var(--mk-font-ui);color:var(--fg-1); }
.wl-meal-mode{ display:inline-flex;align-items:center;gap:4px;margin-inline-start:auto;padding:3px 9px;border-radius:999px;font:700 10.5px/1 var(--mk-font-ui); }
.wl-meal-mode .mi{ font-size:14px; }
.wl-meal-mode.prepare{ background:color-mix(in srgb,var(--mk-ok,#2f9e63) 14%,transparent);color:var(--mk-ok,#2f9e63); }
.wl-meal-mode.expense{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.wl-meal-b{ display:flex;align-items:center;gap:9px;flex-wrap:wrap; }
.wl-meal-menu{ display:inline-flex;align-items:center;gap:5px;font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); } .wl-meal-menu .mi{ font-size:15px;color:var(--accent); }
.wl-meal-note{ font:500 12.5px/1.3 var(--mk-font-ui);color:var(--fg-2); }
.wl-dish .wl-ing{ display:flex;flex-direction:column;gap:1px;padding:6px 0;border-top:1px solid var(--bd-1,#dfe4e8);margin-top:6px; }
.wl-ing-nm{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-ing-meta{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-3); }
/* B60 - the trip's destination TIMELINE (Pablo: destinations "should show up on some
   sort of timeline view", and the date range "can show up on the timeline"). One rail
   drawn by the nodes themselves: each row's dot sits on a 1px line that runs through
   the stack, the two caps carry the trip's start and end date, and a stop is a real
   button - full-width, 44px of touch, with the edit affordance on its trailing end. */
.wl-dtl{ display:flex;flex-direction:column;position:relative;margin:2px 0 4px;padding:2px 0; }
.wl-dtl-node{ position:relative;display:flex;align-items:flex-start;gap:10px;width:100%;
  padding:7px 8px 7px 0;background:transparent;border:0;text-align:start;min-height:40px; }
/* B62 W-22 ("a line connecting the points") — the connector existed as a 1px divider
   hairline and read as nothing beside the 2px accent dots. It is the accent now, at
   2px, so the stops are visibly ONE line. */
.wl-dtl-node::before{ content:'';position:absolute;inset-block:0;inset-inline-start:10.5px;
  width:2px;background:color-mix(in srgb,var(--accent) 38%,var(--divider,var(--border))); }
.wl-dtl-node:first-child::before{ inset-block:50% 0; }
.wl-dtl-node:last-child::before{ inset-block:0 50%; }
.wl-dtl-dot{ position:relative;z-index:1;flex:0 0 auto;width:23px;height:23px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;
  background:var(--bg-1,#fff);border:2px solid var(--accent);color:var(--accent-text,var(--accent));
  font-size:13px;margin-top:1px; }
.wl-dtl-node.is-cap .wl-dtl-dot{ border-color:var(--border-strong,var(--border));color:var(--fg-3); }
.wl-dtl-b{ min-width:0;display:flex;flex-direction:column;gap:2px;flex:1 1 auto; }
.wl-dtl-t{ font:700 13px/1.3 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis; }
.wl-dtl-node.is-cap .wl-dtl-t{ font-weight:600;color:var(--fg-2);font-size:12px; }
/* B62 — a stop's date line is ink the user has to read (it now carries the range),
   and `--fg-3` measured 2.54:1 on the panel. `--fg-2` is the app's answer for that
   (the same call session 6 made for the drawer glyphs). */
.wl-dtl-d{ font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.wl-dtl-stop{ cursor:pointer;border-radius:10px;transition:background var(--mk-t-fast); }
.wl-dtl-stop:hover{ background:color-mix(in srgb,var(--accent) 7%,transparent); }
.wl-dtl-go{ flex:0 0 auto;align-self:center;font-size:16px;color:var(--fg-3);opacity:0;transition:opacity var(--mk-t-fast); }
.wl-dtl-stop:hover .wl-dtl-go,.wl-dtl-stop:focus-visible .wl-dtl-go{ opacity:1; }
@media (pointer:coarse){ .wl-dtl-stop{ min-height:44px; } .wl-dtl-go{ opacity:1; } }
/* B62 W-22 — "the avatar bubbles for the users who will be part of this destination".
   Derived (wlDestPeople), so it says who is really there, not the whole trip. */
.wl-dtl-avs{ display:inline-flex;align-items:center;flex:0 0 auto;align-self:center;margin-inline-start:auto; }
.wl-dtl-avs .wl-avs{ display:inline-flex;align-items:center; }
/* B62 W-20 — the trip's chat row. A `.wl-sumbox` that is a <button> must be pinned to
   100%: a button's `width:auto` is fit-content, which is what made a Jockey summary box
   hang past its column in wave 4. */
.wl-tripchat{ width:100%;min-width:0;text-align:start;cursor:pointer;font:inherit;color:inherit;margin-top:6px; }
.wl-tripchat:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--bd-1,#dfe4e8)); }
.wl-tripchat .wl-avs{ margin-inline-start:auto; }
/* B62 W-67 — a value the form COMPUTES rather than asks for. */
.wl-derived{ margin-top:2px; } .wl-derived b{ color:var(--fg-1);font-variant-numeric:tabular-nums; }
.wl-groc{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;overflow:hidden;background:var(--bg-1,#fff); }
/* B60 - an editable grocery LINE. The table shape is unchanged (Pablo reads it as a
   table and it is one); the row is simply a control now, with the edit affordance on
   its trailing end and a mark when its number is no longer the menus' own. */
.wl-groc-row.wl-groc-click{ grid-template-columns:1fr auto auto auto auto;width:100%;
  border:0;border-bottom:1px solid var(--bd-1,#dfe4e8);background:transparent;
  cursor:pointer;text-align:start;font:inherit;color:inherit;
  transition:background var(--mk-t-fast); }
.wl-groc-row.wl-groc-click:hover{ background:color-mix(in srgb,var(--accent) 7%,transparent); }
.wl-groc-go{ font-size:15px;color:var(--fg-3);opacity:0;transition:opacity var(--mk-t-fast); }
.wl-groc-click:hover .wl-groc-go,.wl-groc-click:focus-visible .wl-groc-go{ opacity:1; }
.wl-groc-mk{ display:inline-block;margin-inline-start:6px;padding:0 6px;border-radius:999px;
  font:700 9.5px/1.7 var(--mk-font-ui);vertical-align:1px;
  background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text,var(--accent)); }
.wl-groc-mk.is-extra{ background:color-mix(in srgb,var(--mk-ok,#22a06b) 16%,transparent);color:var(--mk-ok,#22a06b); }
.wl-chip.wl-chip-bad{ color:var(--mk-danger,#d64545);border-color:color-mix(in srgb,var(--mk-danger,#d64545) 40%,transparent); }
.wl-chip.wl-chip-bad:hover{ background:color-mix(in srgb,var(--mk-danger,#d64545) 12%,transparent); }
@media (pointer:coarse){ .wl-groc-row.wl-groc-click{ min-height:44px; } .wl-groc-go{ opacity:1; } }
.wl-groc-row{ display:grid;grid-template-columns:1fr auto auto auto;gap:10px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--bd-1,#dfe4e8);font:500 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.wl-groc-nm{ min-width:0; } .wl-groc-br{ color:var(--fg-3);font-weight:600; }
.wl-groc-ty{ font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.02em; }
.wl-groc-qty{ font-variant-numeric:tabular-nums;color:var(--fg-2);font-weight:600; }
.wl-groc-total{ display:flex;justify-content:space-between;padding:9px 12px;font:800 13px/1 var(--mk-font-ui);color:var(--fg-1);background:var(--bg-2,#f7f8fa);font-variant-numeric:tabular-nums; }
.wl-menu-ed{ display:flex;flex-direction:column;gap:7px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:11px 12px;background:var(--bg-1,#fff);margin-bottom:8px; }
.wl-ing-ed{ display:flex;align-items:center;gap:6px;flex-wrap:wrap; }
.wl-ing-ed input[data-ing="nm"]{ flex:1 1 120px;min-width:0; } .wl-ing-ed select[data-ing="ptype"]{ flex:0 0 auto; } .wl-ing-ed input[data-ing="brand"],.wl-ing-ed input[data-ing="plu"]{ flex:1 1 90px;min-width:0; }
.wl-ing-qty{ display:inline-flex;align-items:center;gap:5px;flex:0 0 auto; } .wl-ing-qty input.num{ width:64px; } .wl-ing-qty select{ width:64px; }
.wl-meal-ed{ display:flex;flex-direction:column;gap:7px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:11px 12px;background:var(--bg-1,#fff);margin-bottom:8px; }

/* ── B39 C36/C37 — Pay / Nudge debt actions ── */
.wl-debt-btn{ display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;border:0;border-radius:999px;padding:6px 12px;font:700 11.5px/1 var(--mk-font-ui);cursor:pointer;margin-inline-start:8px; }
.wl-debt-btn .mi{ font-size:15px; }
.wl-debt-btn.pay{ background:var(--accent);color:#fff; } .wl-debt-btn.pay:hover{ filter:brightness(1.06); }
.wl-debt-btn.nudge{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); } .wl-debt-btn.nudge:hover{ background:color-mix(in srgb,var(--accent) 20%,transparent); }
.wl-debt-state{ display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;margin-inline-start:8px;font:700 11px/1 var(--mk-font-ui);color:var(--fg-3); } .wl-debt-state .mi{ font-size:15px; } .wl-debt-state.ok{ color:var(--mk-ok,#2f9e63); }
.wl-amt-settled{ text-decoration:line-through;opacity:.55; }
.wl-pay-hd{ display:flex;align-items:center;gap:11px;padding:12px 14px;border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff);margin-bottom:6px; }
.wl-pay-hd-m{ display:flex;flex-direction:column;gap:2px;flex:1;min-width:0; }
.wl-pay-hd-nm{ font:700 14px/1.2 var(--mk-font-ui);color:var(--fg-1); } .wl-pay-hd-sub{ font:500 11.5px/1.2 var(--mk-font-ui);color:var(--fg-3); }
.wl-pay-amt{ font:800 18px/1 var(--mk-font-ui);color:var(--accent);font-variant-numeric:tabular-nums; }
.wl-pid-copy{ cursor:pointer; } .wl-pid-copy:hover{ border-color:var(--accent); }
.wl-pid-copybtn{ margin-inline-start:auto;font-size:17px;color:var(--fg-3);flex:0 0 auto; } .wl-pid-copy:hover .wl-pid-copybtn{ color:var(--accent); }
.wl-att{ display:flex;align-items:center;gap:8px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:11px;background:var(--bg-1,#fff);font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); } .wl-att .mi{ color:var(--accent); } .wl-att .wl-x{ margin-inline-start:auto; }
.wl-pay-ta{ min-height:70px;resize:vertical;padding:9px 11px;font-family:var(--mk-font-ui); }
/* B57 — the attachment chip's editable name (the chat composer's affordance, in
   every form). The extension is a locked span, so only the base name is edited. */
.wl-att-nm{ flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:text; }
.wl-att-nm:hover{ text-decoration:underline dotted; }
.wl-att-ext{ color:var(--fg-3);font-weight:600; }
.wl-att-nm-inp{ font:inherit;color:var(--fg-1);border:0;background:transparent;outline:0;width:10ch;min-width:50px;max-width:160px;padding:0; }
/* the COMPLEX text field — the shared composer sitting inside a wallet form */
.wl-rich{ margin-bottom:4px; }
.wl-rich .composer{ width:100%; }
.wl-rich .ast-input{ min-height:56px; }
/* B39 C44 — fee split modes */
.wl-fee-payers{ flex-direction:column;align-items:stretch; }
.wl-splitmode{ display:inline-flex;flex-wrap:wrap;border:1px solid var(--bd-1,#dfe4e8);border-radius:9px;overflow:hidden;align-self:flex-start; }
.wl-splitmode button{ border:0;background:transparent;font:700 11px/1 var(--mk-font-ui);color:var(--fg-3);padding:7px 11px;cursor:pointer;border-inline-end:1px solid var(--bd-1,#dfe4e8); }
.wl-splitmode button:last-child{ border-inline-end:0; }
.wl-splitmode button.on{ background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.wl-fee-picks{ display:flex;flex-wrap:wrap;gap:6px;margin-top:6px; }
.wl-fee-amts{ display:flex;flex-wrap:wrap;gap:8px;margin-top:6px; }
.wl-fee-amt{ display:inline-flex;align-items:center;gap:5px;font:700 11px/1 var(--mk-font-ui);color:var(--fg-2); } .wl-fee-amt input.num{ width:74px; }

/* ── B35 S10 — Buraco ── */
.bu-closed{ font:700 10.5px/1 var(--mk-font-ui);color:var(--mk-ok,#2f9e63);text-transform:none;letter-spacing:.04em; }
.bu-table{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;overflow:hidden;background:var(--bg-1,#fff); }
.bu-tr{ display:grid;grid-template-columns:64px repeat(auto-fit,minmax(70px,1fr));gap:6px;padding:8px 12px;border-bottom:1px solid var(--bd-1,#dfe4e8);font:500 12.5px/1.2 var(--mk-font-ui);color:var(--fg-2);align-items:center; }
.bu-tr:last-child{ border-bottom:0; }
.bu-th{ font-weight:700;font-size:11px;text-transform:none;letter-spacing:.05em;color:var(--fg-3);background:var(--bg-2,#f7f8fa); }
.bu-tf{ font-weight:800;background:var(--bg-2,#f7f8fa); }
.bu-v{ font-variant-numeric:tabular-nums;font-weight:700; }
.bu-v.neg{ color:var(--mk-danger,#d64545); } .bu-v.pos{ color:var(--fg-1); } .bu-tf .bu-v.pos{ color:var(--mk-ok,#2f9e63); }
.bu-score-btn{ margin-top:10px; }
/* B62 W-66 (\"I can't test the 3k points threshold to close a set\") — the OPEN set's
   race to the target, drawn with the app's own bar. One row per side: who, how far,
   how much is left. This is the surface the threshold is tested on. */
.bu-race{ display:flex;flex-direction:column;gap:9px;margin-top:12px;padding:11px 12px;
  border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff); }
.bu-race-h{ display:flex;align-items:center;gap:6px;font:700 11px/1 var(--mk-font-ui);color:var(--fg-3);letter-spacing:.03em; }
.bu-race-h .mi{ font-size:15px;color:var(--accent-text,var(--accent)); }
.bu-race-closed{ margin-inline-start:auto;font:800 10px/1 var(--mk-font-ui);color:var(--mk-ok,#2f9e63);
  background:color-mix(in srgb,var(--mk-ok,#2f9e63) 13%,transparent);padding:3px 8px;border-radius:999px; }
.bu-race-row{ display:grid;grid-template-columns:minmax(90px,1.1fr) minmax(60px,2fr) auto;gap:10px;align-items:center; }
.bu-race-nm{ display:inline-flex;align-items:center;gap:5px;min-width:0;font:600 12px/1.2 var(--mk-font-ui);color:var(--fg-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.bu-race-v{ display:inline-flex;flex-direction:column;align-items:flex-end;gap:1px;flex:0 0 auto; }
.bu-race-v b{ font:800 12.5px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.bu-race-v em{ font:600 10px/1 var(--mk-font-ui);font-style:normal;color:var(--fg-2);white-space:nowrap; }
@media (max-width:520px){ .bu-race-row{ grid-template-columns:1fr auto;grid-template-areas:'nm v' 'bar bar';row-gap:6px }
  .bu-race-nm{ grid-area:nm } .bu-race-v{ grid-area:v } .bu-race-row > .wl-pmcb{ grid-area:bar } }
/* the one-shot line that says a set just closed — the only reason a redraw looks
   different from the one before it. */
.bu-closed-note{ display:flex;align-items:center;gap:8px;margin-top:10px;padding:9px 11px;border-radius:11px;
  background:color-mix(in srgb,var(--mk-ok,#2f9e63) 12%,transparent);
  font:700 12px/1.3 var(--mk-font-ui);color:color-mix(in srgb,var(--mk-ok,#2f9e63) 82%,var(--fg-1)); }
.bu-closed-note .mi{ font-size:18px;color:var(--mk-ok,#2f9e63);flex:0 0 auto; }
.bu-step{ font:600 11px/1 var(--mk-font-ui);color:var(--fg-3);margin-inline-start:auto; }
.bu-form{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;padding:13px;background:var(--bg-1,#fff);display:flex;flex-direction:column;gap:10px; }
.bu-check{ display:flex;align-items:center;gap:8px;font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1);cursor:pointer; }
/* B55 — the score form names the dealer, because the exact-deal toggle now
   appears on ONE side only and an unexplained absence reads as a bug. */
.bu-dealer-note{ display:flex;align-items:center;gap:7px;margin-bottom:10px;padding:7px 10px;
  border-radius:10px;background:color-mix(in srgb,var(--accent) 9%,transparent);
  font:600 12px/1.3 var(--mk-font-ui);color:var(--fg-1); }
.bu-dealer-note .mi{ font-size:16px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.bu-lbl{ font:700 11px/1 var(--mk-font-ui);color:var(--fg-3);text-transform:none;letter-spacing:.05em;margin-top:2px; }
.bu-baskets{ display:flex;flex-wrap:wrap;gap:6px; }
.bu-bk{ padding:6px 10px;border-radius:999px;border:1px solid var(--bd-1,#dfe4e8);background:var(--bg-1,#fff);font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2);cursor:pointer; }
.bu-bk b{ font-weight:800; }
.bu-bk.on{ border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent); }
.bu-preview{ font:600 13px/1.4 var(--mk-font-ui);color:var(--fg-2);padding-top:6px;border-top:1px dashed var(--bd-1,#dfe4e8); }
.bu-warn{ display:inline-flex;align-items:center;gap:4px;color:#a67c00;font-size:11.5px;margin-inline-start:8px; }
.bu-warn .mi{ font-size:14px; }
/* B51-28 — the match-score BREAKDOWN. Reads as a receipt: one row per addend in
   play, the total on a hairline. Same neg/pos tone tokens the rest of the buraco
   form uses, so a negative addend is legible at a glance. */
.bu-calc{ display:flex;flex-direction:column;gap:1px;margin-top:8px;padding:8px 10px;
  border-radius:10px;background:var(--bg-2);border:1px solid var(--divider); }
.bu-calc-r{ display:flex;align-items:baseline;gap:10px;justify-content:space-between; }
.bu-calc-l{ font:500 11.5px/1.5 var(--mk-font-ui);color:var(--fg-2);min-width:0; }
.bu-calc-l em{ font-style:normal;font-weight:600;color:#a67c00; }
.bu-calc-v{ font:700 12px/1.5 var(--mk-font-mono,ui-monospace,monospace);font-variant-numeric:tabular-nums;flex:0 0 auto; }
.bu-calc-v.pos{ color:var(--fg-1); }
.bu-calc-v.neg{ color:var(--mk-danger); }
.bu-calc-t{ margin-top:5px;padding-top:5px;border-top:1px solid var(--divider); }
.bu-calc-t .bu-calc-l{ font-weight:700;color:var(--fg-1); }
.bu-calc-t .bu-calc-v{ font-size:14px; }
.bu-form-btns{ display:flex;justify-content:flex-end;gap:8px; }
/* B39 C23/C24 — ranking + one-slide collapsible score form */
.bu-rank{ display:flex;flex-direction:column;gap:4px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;overflow:hidden;background:var(--bg-1,#fff); }
.bu-rank-row{ display:flex;align-items:center;gap:10px;padding:10px 12px;cursor:pointer;border-bottom:1px solid var(--bd-1,#dfe4e8); }
.bu-rank-row:hover{ background:var(--bg-2,#f7f8fa); }
.bu-rank-pos{ width:22px;height:22px;flex:0 0 auto;display:grid;place-items:center;border-radius:999px;background:var(--bg-2,#f7f8fa);font:800 11.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.bu-rank-row:first-child .bu-rank-pos{ background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent); }
.bu-rank-nm{ flex:1;min-width:0;display:flex;align-items:center;gap:6px;font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.bu-rank-tot{ font:800 14px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.bu-caret{ font-size:18px;color:var(--fg-3);transition:transform .15s; }
.bu-rank-row.open .bu-caret,.bu-rank-set.open .bu-caret{ transform:rotate(180deg); }
.bu-rank-set .bu-caret{ font-size:16px; }.bu-rank-set.open .bu-caret{ transform:rotate(90deg); }
.bu-rank-detail{ background:var(--bg-2,#f7f8fa);border-bottom:1px solid var(--bd-1,#dfe4e8);padding:4px 10px 8px; }
.bu-rank-set{ display:flex;align-items:center;gap:8px;padding:7px 6px;cursor:pointer;font:600 12px/1.2 var(--mk-font-ui);color:var(--fg-2); }
.bu-rank-set > span:nth-child(2){ flex:1; } .bu-rank-set .bu-v{ font-weight:800; }
.bu-rank-matches{ padding:2px 6px 6px 24px;display:flex;flex-direction:column;gap:3px; }
.bu-mrow{ display:flex;justify-content:space-between;font:500 11.5px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums; }
.bu-mrow.bu-empty{ color:var(--fg-3);font-style:italic; }
.bu-sec{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;margin-bottom:8px;overflow:hidden;background:var(--bg-1,#fff); }
.bu-sec-h{ display:flex;align-items:center;gap:9px;padding:10px 12px;cursor:pointer; }
.bu-sec-h:hover{ background:var(--bg-2,#f7f8fa); }
.bu-sec-nm{ flex:1;min-width:0;display:flex;align-items:center;gap:6px;font:600 13px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.bu-sec-h .bu-v{ font:800 14px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.bu-sec.open > .bu-sec-h .bu-caret{ transform:rotate(180deg); }
.bu-sec-b{ display:flex;flex-direction:column;gap:9px;padding:0 12px 12px;border-top:1px solid var(--bd-1,#dfe4e8);padding-top:10px; }
/* B50-13 — same trap: the buraco section body is collapsed via `hidden`, so the
   display above kept every section expanded and the caret did nothing. */
.bu-sec-b[hidden]{ display:none; }

/* ── B35 S11b — Icons lab ── */
.ic-lab{ display:flex;flex-direction:column;gap:16px; }
.ic-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:9px; }
.ic-card{ display:flex;flex-direction:column;align-items:center;gap:6px;padding:13px 8px 10px;border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff);cursor:pointer;font-family:var(--mk-font-ui); }
.ic-card.on{ border-color:var(--accent);box-shadow:0 3px 12px color-mix(in srgb,var(--accent) 14%,transparent); }
.ic-thumb{ height:32px;display:grid;place-items:center;color:var(--fg-1); }
.ic-nm{ font:600 11.5px/1.2 var(--mk-font-ui);color:var(--fg-1);text-align:center; }
.ic-tag{ font:500 9.5px/1 var(--mk-font-ui);color:var(--fg-3);text-transform:none;letter-spacing:.05em; }
.ic-builder{ border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff);overflow:hidden; }
.ic-b-head{ display:flex;align-items:center;gap:9px;padding:12px 16px;border-bottom:1px solid var(--bd-1,#dfe4e8);font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.ic-b-head .mi{ color:var(--accent); }
.ic-key{ font:600 11px var(--mk-font-mono,monospace);color:var(--fg-3);background:var(--bg-2,#f6f7f9);padding:3px 8px;border-radius:6px; }
.ic-b-body{ display:grid;grid-template-columns:minmax(220px,300px) 1fr;gap:0; }
@media (max-width:760px){ .ic-b-body{ grid-template-columns:1fr; } }
.ic-preview-col{ padding:14px 16px;border-inline-end:1px solid var(--bd-1,#dfe4e8);display:flex;flex-direction:column;gap:9px; }
@media (max-width:760px){ .ic-preview-col{ border-inline-end:0;border-bottom:1px solid var(--bd-1,#dfe4e8); } }
.ic-prev-lbl{ font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);text-transform:none;letter-spacing:.05em; }
.ic-prev-row{ display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap; }
.ic-prev-box{ display:grid;place-items:center;padding:8px;border:1px dashed var(--bd-1,#dfe4e8);border-radius:10px;color:var(--fg-1); }
.ic-prev-dark .ic-prev-box{ background:#1b2027;border-color:#333b46; }
.ic-nodes{ padding:14px 16px;display:flex;flex-direction:column;gap:8px; }
.ic-node{ display:flex;align-items:center;gap:9px;padding:9px 12px;border:1px solid var(--bd-1,#dfe4e8);border-radius:10px;flex-wrap:wrap; }
.ic-node-kind{ display:inline-flex;align-items:center;gap:5px;font:700 11px/1 var(--mk-font-ui);color:var(--fg-2);text-transform:none;letter-spacing:.04em; }
.ic-node-kind .mi{ font-size:15px;color:var(--accent); }
.ic-node-d{ font:500 11px var(--mk-font-mono,monospace);color:var(--fg-3);flex:1;min-width:120px; }
.ic-bind{ display:inline-flex;align-items:center;gap:4px;font:600 10.5px/1 var(--mk-font-ui);padding:4px 9px;border-radius:999px;background:color-mix(in srgb,var(--accent) 11%,transparent);color:var(--accent); }
.ic-bind .mi{ font-size:13px; }
.ic-bind.ic-b-static{ background:var(--bg-2,#f4f5f7);color:var(--fg-3); }
.brand-badge.ic-driven svg,.nav-brand-badge.ic-driven svg{ display:block; }

/* ── B35 S6 — role groups (cohorts) ── */
.rg-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px;margin-bottom:6px; }
.rg-card{ border:1px solid var(--bd-1,#dfe4e8);border-radius:14px;background:var(--bg-1,#fff);padding:14px 15px;display:flex;flex-direction:column;gap:11px; }
.rg-h{ display:flex;align-items:center;gap:10px; }
.rg-ic{ width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent); }
.rg-hh{ display:flex;flex-direction:column;gap:2px; }
.rg-nm{ font:700 14px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.rg-sub{ font:500 11.5px/1 var(--mk-font-ui);color:var(--fg-3); }
.rg-vars{ display:flex;flex-direction:column;gap:6px; }
.rg-var{ display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 11px;border:1px solid var(--bd-1,#dfe4e8);border-radius:9px; }
.rg-var-nm{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1); }
.rg-var-ct{ display:inline-flex;align-items:center;gap:4px;font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-3); }
.rg-var-ct .mi{ font-size:14px; }
.rg-chips{ display:flex;flex-wrap:wrap;gap:5px;justify-content:flex-end;max-width:55%; }
.rg-chip{ font:500 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2);padding:4px 9px;border-radius:999px;background:var(--bg-2,#f4f5f7);border:1px solid var(--bd-1,#dfe4e8); }
.rg-chip b{ font-weight:700;color:var(--fg-1); }

/* ── B35 C8 — chat voice note ── */
.cmp-ico.rec{ color:#d64545; }
.cmp-rec .cmp-rec-dot{ color:#d64545;animation:astRecPulse 1.1s infinite; }
.cmp-att-voice .mi{ color:var(--accent); }
.cmp-att-meta{ font:500 10.5px var(--mk-font-ui);color:var(--fg-3);margin-inline-start:2px; }
@keyframes astRecPulse{ 0%,100%{opacity:1} 50%{opacity:.35} }


/* ── B44 C31-C36 — backend node view/edit panels + permissions form ── */
.nv-kids{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.nv-kid{margin:0}
.nv-form{display:flex;flex-direction:column;gap:14px}
.nv-hint{font-size:12px;color:var(--muted,#8a94a6);line-height:1.45;margin-top:-6px}
.nv-kind-row{display:flex;gap:10px;margin-top:6px}
.nv-kind-col{flex-direction:column}
.nv-kind-opt{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px 14px;border:1.5px solid var(--border,#d6dce6);border-radius:12px;background:transparent;cursor:pointer;font:inherit;color:inherit;text-align:start}
.nv-kind-opt:hover{border-color:var(--accent,#03c9cb)}
.nv-kind-opt.on{border-color:var(--accent,#03c9cb);box-shadow:0 0 0 3px var(--ring,rgba(3,201,203,.25))}
.nv-kind-opt>.mi{font-size:20px;color:var(--accent,#03c9cb)}
.nv-ko-t{font-weight:700;font-size:13.5px}
.nv-ko-s{font-size:11.5px;color:var(--muted,#8a94a6);line-height:1.4}
.nv-stg-row{margin-top:12px}
.ent-perm-form{display:flex;flex-direction:column;gap:8px;padding-top:2px}
.ent-perm-sech{margin-top:8px}


/* ── B45 C28 — icon binding editor: source .cs dropdown + color chip/popover ── */
.ic-bind-ed{ display:flex;align-items:center;gap:6px;flex-wrap:wrap; }
.ic-cs{ position:relative; }
.ic-cs .cs-btn{ display:inline-flex;align-items:center;gap:5px;padding:5px 9px;border:1px solid var(--border);border-radius:8px;background:var(--bg-input);cursor:pointer;font:600 12px var(--mk-font-ui);color:var(--fg-1); }
.ic-cs .cs-arrow{ font-size:15px;color:var(--fg-3); }
.ic-cs .cs-menu{ display:none;position:absolute;z-index:40;top:calc(100% + 4px);left:0;min-width:150px;background:var(--bg-1);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow-md);padding:4px; }
.ic-cs.open .cs-menu{ display:block; }
.ic-cs .cs-item{ padding:7px 9px;border-radius:7px;cursor:pointer;font:600 12px var(--mk-font-ui);color:var(--fg-1); }
.ic-cs .cs-item:hover,.ic-cs .cs-item.on{ background:var(--accent-soft);color:var(--accent-text); }
.ic-color-chip{ display:inline-flex;align-items:center;gap:6px;padding:4px 9px 4px 5px;border:1px solid var(--border);border-radius:8px;background:var(--bg-input);cursor:pointer;font:600 11.5px var(--mk-font-mono);color:var(--fg-1); }
.ic-color-chip .ic-sw{ width:16px;height:16px;border-radius:5px;background:var(--sw);box-shadow:inset 0 0 0 1px rgba(0,0,0,.15); }
.ic-color-fb{ padding:4px; }
.ic-rx-input{ width:64px; }
.ic-color-pop{ position:fixed;z-index:2200;width:224px;background:var(--bg-1);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow-lg,0 18px 48px rgba(13,37,48,.24));padding:10px;display:flex;flex-direction:column;gap:9px; }
.ic-cp-swatches{ display:grid;grid-template-columns:repeat(6,1fr);gap:5px; }
.ic-cp-sw{ aspect-ratio:1;border-radius:6px;border:1px solid rgba(0,0,0,.12);cursor:pointer;padding:0; }
.ic-cp-sw.on{ box-shadow:0 0 0 2px var(--accent); }
.ic-cp-row{ display:flex;align-items:center;gap:7px; }
.ic-cp-native{ width:34px;height:30px;border:1px solid var(--border);border-radius:7px;background:none;padding:0;cursor:pointer;flex:0 0 auto; }
.ic-cp-val{ flex:1;min-width:0;border:1px solid var(--border);border-radius:7px;padding:6px 8px;font:600 11.5px var(--mk-font-mono);background:var(--bg-input);color:var(--fg-1); }
.ic-cp-fmts{ display:flex;gap:4px; }
/* B46 C29 — eyedropper button + screen-pick overlay. */
.ic-cp-drop{ width:30px;height:30px;flex:0 0 auto;display:grid;place-items:center;padding:0;
  border:1px solid var(--border);border-radius:7px;background:var(--bg-input);color:var(--fg-2);cursor:pointer; }
.ic-cp-drop:hover{ border-color:var(--accent);color:var(--accent-text); }
.ic-cp-drop .mi{ font-size:16px;line-height:1; }
.ic-drop-ov{ position:fixed;inset:0;z-index:100000;cursor:crosshair; }
.ic-drop-hint{ position:fixed;left:50%;bottom:26px;transform:translateX(-50%);display:flex;align-items:center;gap:9px;
  padding:9px 14px;border-radius:999px;background:var(--fg-1);color:var(--bg-1);
  font:700 12px var(--mk-font-mono, ui-monospace, monospace);letter-spacing:.02em;
  box-shadow:0 10px 30px rgba(0,0,0,.28);pointer-events:none;white-space:nowrap; }
.ic-drop-hint .mi{ font-size:16px; }
.ic-drop-prev{ width:20px;height:20px;border-radius:6px;border:2px solid var(--bg-1);background:#fff; }
.ic-cp-fmt{ flex:1;padding:5px 0;border:1px solid var(--border);border-radius:7px;background:var(--bg-input);cursor:pointer;font:700 10px var(--mk-font-ui);letter-spacing:.03em;color:var(--fg-2); }
.ic-cp-fmt.on{ background:var(--accent);border-color:var(--accent);color:var(--accent-fg); }


/* B46 C26 (Pablo: "we already have a Close button in the panel, this is
   redundant") — the route-preview dock's own full-screen close is dropped; the
   route panel's close (plus Esc / outside-click) owns dismissal. */
#rtPreviewDock > .rt-pv-fs-close{ display:none !important; }
/* ── B45 C26 — route preview: live iframe + orientation toggle ── */
/* B51-19 (Pablo: "This 'Route preview' is kind of irrelevant") — the title is
   gone; the bar now holds only the variant control, centred over the device. */
.rt-pv-bar-c{ justify-content:center; }
.rt-pv-frame-live{ transform-origin:top left;overflow:hidden;border-radius:14px;box-shadow:0 12px 40px rgba(0,0,0,.3);background:var(--bg-1); }
.rt-pv-iframe{ width:100%;height:100%;border:0;display:block;background:var(--bg-1); }
.rt-pv-sep{ display:inline-block;width:1px;height:18px;background:var(--border);margin:0 4px;vertical-align:middle; }
.rt-pv-orient .mi{ font-size:17px; }
/* the embedded prototype hides the route Create pill / preview docks + any FAB */
body.rtpv-embed #routeCreateWrap,body.rtpv-embed #routeFab,body.rtpv-embed #rtPreviewDock,body.rtpv-embed .cmp-preview-dock{ display:none !important; }


/* ── B59 — the recipient is two ordinary fields ────────────────────
   Pablo: "I don't like the idea of the recipient being a nested dropdown. We didn't
   have components like this for a reason, I don't want a new component, we would have
   a field for recipient type and another for recipient." The B45 C2 fused button and
   its drill-down popover (`.wl-recip-fused`, `.wl-recip-pop*`, ~26 rules) are deleted
   — not overridden — because the markup that used them is gone. What is left is two
   `.ent-input` selects, each with the same mini label every other wallet field uses. */
.wl-recip2-f{ display:flex;flex-direction:column;gap:3px;flex:1 1 130px;min-width:0; }
.wl-recip2-f > .ent-input{ width:100%;min-width:0; }
.wl-recip2{ flex-wrap:wrap; }
.wl-recip-ovrow{ align-items:flex-start; }
@media (max-width:520px){ .wl-recip2-f{ flex:1 1 100%; } }



/* ── B45 C3 — Destinations component (sortable). B57 turned the ROW into the app's
   own `.wl-sumbox` (Pablo: "The destinations of a trip should be boxes…"), so the
   only thing this block still owns is the drag grip and the dragging state — the
   box's own look comes from .wl-sumbox like every other summary box. The stacked
   inline-control layout (.wl-dest-main, .wl-dest-timechip, .wl-dest-del) went with
   the inline form. */
.wl-dest-list{ display:flex;flex-direction:column;gap:6px;margin-bottom:8px; }
.wl-dest-box{ cursor:pointer; }
.wl-dest-box.wl-dragging{ opacity:.5; }
.wl-dest-grip{ font-size:18px;color:var(--fg-3);cursor:grab;flex:0 0 auto; }
/* a summary box standing in for a record with no name yet */
.wl-unnamed{ font-style:italic;color:var(--fg-3); }
.wl-sumbox[data-ibox],.wl-sumbox[data-mbox],.wl-sumbox[data-vbox]{ cursor:pointer; }
.wl-sumbox[data-ibox]:hover,.wl-sumbox[data-mbox]:hover,.wl-sumbox[data-vbox]:hover,.wl-dest-box:hover{ border-color:color-mix(in srgb,var(--accent) 45%,transparent); }
/* B50-15 — the optional-time control is a persistent, LABELLED toggle (it used to
   be a bare unstyled `timer_off` icon that vanished once clicked). */
.wl-dest-timechip{ align-self:flex-start;display:inline-flex;align-items:center;gap:5px;min-height:28px;padding:4px 10px;border:1px dashed color-mix(in srgb,var(--accent) 40%,var(--bd-1,#dfe4e8));border-radius:999px;background:none;cursor:pointer;font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2); }
.wl-dest-timechip .mi{ font-size:15px; }
.wl-dest-timechip:hover{ border-color:var(--accent);color:var(--accent-text,var(--accent));background:var(--accent-soft); }
.wl-dest-timechip.on{ border-style:solid;border-color:color-mix(in srgb,var(--accent) 55%,transparent);background:var(--accent-soft);color:var(--accent-text,var(--accent));font-variant-numeric:tabular-nums; }
@media (pointer:coarse){ .wl-dest-timechip{ min-height:44px;padding:4px 14px; } }
.wl-dest-box .wl-dt-btn{ display:flex;align-items:center;gap:6px;justify-content:flex-start;text-align:start; }
.wl-chip-sub{ opacity:.7;font-weight:500;margin-inline-start:4px; }
/* VC-18a — mirror the static forward-drill chevrons in RTL so every drill
   affordance points consistently. Only the pure horizontal "go/open" arrows
   (never the tree carets that rotate on expand, nor the breadcrumb chevrons
   that already swap glyph programmatically). */
html[dir="rtl"] .ent-open,
html[dir="rtl"] .cmp-kid-go,
html[dir="rtl"] .pe-card-chev{ transform:scaleX(-1); }

/* WAVE 2 — the resolved help text from the field layer, as a hint glyph beside a
   label (the label itself stays short; the tooltip carries the help AND which
   layer set it). */
.wl-reg-help{ display:inline-flex;vertical-align:-2px;margin-inline-start:4px;color:var(--fg-3); }
.wl-reg-help .mi{ font-size:13px; }
.wl-reg-help:hover{ color:var(--accent-text); }

/* ══ B61 — the route editor speaks the app's one collection grammar ══════
   Pablo: "Stop proposing new components of complex objects in an item on the
   form. We have the box that opens a new slide component down in this
   prototype please make sure this is a standard in the prototype."
   Every collection here is now a .wl-sumbox that opens a pushed slide, so the
   only NEW css is the button affordance the sumbox never needed before. */
.rt-ed-boxes{ display:flex;flex-direction:column;gap:6px;margin:2px 0 4px; }
.rt-box{ width:100%;text-align:start;cursor:pointer;font:inherit;color:inherit; }
.rt-box:hover{ border-color:var(--accent); }
.rt-box:focus-visible{ outline:2px solid var(--accent);outline-offset:1px; }
.rt-box-ic{ font-size:17px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.rt-box-caret{ font-size:17px;color:var(--fg-3);flex:0 0 auto; }
.rt-box.is-empty .wl-sumbox-s{ color:var(--fg-3);font-style:italic; }
.rt-boxrow{ display:flex;align-items:center;gap:5px; }
.rt-boxrow .rt-box{ flex:1;min-width:0; }
.rt-boxrow + .rt-boxrow{ margin-top:6px; }
/* a call row is a way IN now, so it reads like one */
.rt-comp-main[data-c-open]{ cursor:pointer; }
.rt-comp-main[data-c-open]:hover{ background:var(--bg-2,#f4f6f8); }
.rt-comp-caret{ font-size:17px;color:var(--fg-3); }
.rt-binds-slide{ display:flex;flex-direction:column;gap:7px;padding:2px 0; }
.rt-bind-note{ display:flex;align-items:flex-start;gap:8px;padding:9px 11px;margin:0 0 10px;
  border-radius:10px;background:var(--bg-2,#f4f6f8); }
.rt-bind-note .mi{ font-size:16px;color:var(--accent-text,var(--accent));flex:0 0 auto; }
.rt-bind-note p{ margin:0;font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-2); }
/* the default-sort slide reuses the Sort panel's own row chrome (.sort-row,
   .sort-ord, .sort-dir-btn, .sort-rm) — only the field control is local */
.rt-sort-list{ display:flex;flex-direction:column;gap:6px;margin-bottom:8px; }
.rt-sort-row .rt-sort-f{ flex:1;min-width:0; }

/* ══ B61 — the ICON panel's preview dock ═════════════════════════════════
   Pablo: "There is a preview of the icon here but I feel like we're wasting
   space. We already have a preview working on other entities in front end" +
   "When I'm on the panel of an icon. I should be able to see the preview.
   Basically all the tabs in the Front End sub menu item should have a preview.
   The icon also shows an animation of a color gradient bordering the path that
   is being hovered on (both in the form and in the preview)".
   The shell IS .cmp-preview-dock (components-lab.css) — only the icon-specific
   stage is new. The ring itself is the shared one from preview-variants.js. */
.ic-pv-host{ z-index:1240; }
.ic-pv-mount{ flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:20px;padding:26px;overflow:auto; }
.ic-pv-host .rt-pv-bar{ margin-bottom:2px;color:#dfe6f0; }
.ic-pv-stage{ display:grid;place-items:center;padding:22px;border-radius:16px;
  background:#fff;box-shadow:0 10px 34px rgba(6,20,28,.28); }
/* every node is its own stacked layer, so a node has a real box to ring */
.ic-pv-board{ position:relative;width:200px;height:200px; }
.ic-pv-layer{ position:absolute;inset:0;display:grid;place-items:center;cursor:pointer; }
.ic-pv-layer svg{ width:100%;height:100%; }
.ic-pv-sizes{ display:flex;align-items:flex-end;gap:16px;padding:10px 14px;border-radius:12px;
  background:rgba(255,255,255,.9); }
.ic-pv-sizes.ic-pv-dark{ background:#131a22; }
.ic-pv-size{ display:flex;flex-direction:column;align-items:center;gap:5px; }
.ic-pv-size-b{ display:grid;place-items:center;min-height:48px; }
.ic-pv-size em{ font:600 9.5px/1 var(--mk-font-ui);font-style:normal;color:var(--fg-3); }
.ic-pv-dark .ic-pv-size em{ color:#8e9bab; }
/* B61 — a shape child is a BOX that opens a slide (Pablo: "No more components of
   a complex object inside one instance of the paths in the icon. Again, I want
   boxes that open up a new slide in the panel"). */
.ic-node-boxes{ display:flex;flex-direction:column;gap:6px;margin:2px 0 8px; }
.ic-node-box{ display:flex;align-items:center;gap:5px; }
.ic-node-open{ flex:1;min-width:0;text-align:start;cursor:pointer;font:inherit;color:inherit; }
.ic-node-open:hover{ border-color:var(--accent); }
.ic-node-open .wl-sumbox-s{ font-family:var(--mk-font-mono);font-size:10.5px; }
.ic-node-box.is-ringed .ic-node-open{ border-color:var(--accent);
  box-shadow:0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent); }
.ic-node.is-ringed,.ic-node[data-icnode]:hover{ border-color:var(--accent); }
.ic-slide .ic-bind-row{ margin-top:8px; }

/* B61 (Pablo: "I'm standing on an entity in staging but I can't see the edit
   button on the panel") - the entity panel's header Edit action, gated to
   staging exactly like the icon panel's (#iconPanel [data-icp-edit]). */
#entityPanel [data-ent-edit]{ display:grid; }
body:not([data-env="staging"]) #entityPanel [data-ent-edit]{ display:none !important; }
/* B61 - the node panel's ONE fixed footer (Pablo: "the Save and Cancel buttons
   are different here. I liked the fixed bar at the bottom of a panel"). The
   .nt-ed-acts pair that used to scroll inside the form is gone. */
#nodeViewPanel [data-nv-ft]{ flex:0 0 auto; }
.nv-ck-seg{ margin-top:2px; }
.nv-ck-seg .mi{ font-size:15px;margin-inline-end:5px; }

/* B61 - the icon dock gets the route dock's mobile/tablet path: fullscreen behind
   the panel header's eye button, because .cmp-preview-dock is display:none below
   desktop and a dock with no fullscreen path is a preview that only exists on big
   screens. Same breakpoints, same id-specificity trick, same reasoning as
   aside#rtPreviewDock.fs-open above. */
@media (max-width:600px),
       (max-height:599px) and (orientation:landscape),
       (min-width:601px) and (max-width:1024px) and (min-height:600px){
  aside#icPreviewDock.fs-open{ display:flex !important;opacity:1;position:fixed;inset:0 !important;z-index:1500; }
}
/* the eye only makes sense where the dock is hidden */
@media (min-width:1025px), (min-width:601px) and (max-height:599px) and (orientation:landscape){
  #iconPanel [data-icp-preview]{ display:none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   B62 WAVE 2 — the trip panel as its BOARD (W-08, candidate B, picked by
   Pablo from samples/trip-b-stage-rows.html: "boxes the user can go inside,
   which opens a new slide. Simplicity on components please").

   Eight stage rows in his order, each carrying its own state and opening a
   full slide. Nothing here invents a new panel grammar: a row is the
   .wl-sumbox proportions with a state line, and every slide is the panel's
   own .ent-slide-pushed. What IS new is only what the model made possible —
   the phase strip, the per-night bed grid and the balance box.
   ═══════════════════════════════════════════════════════════════════════ */
.wl-phase{ display:flex;gap:0;margin:0 0 12px;padding:2px;border:1px solid var(--border);
  border-radius:12px;background:var(--bg-2);overflow:hidden; }
/* B62 wave 4 (W-07) — the strip is a set of DOORS now: every chip opens its
   phase, so it takes a pointer, a hover and a real tap target. */
.wl-phase-s{ flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:7px 2px 6px;min-height:44px;border-radius:10px;font:700 9.5px/1.15 var(--mk-font-ui);color:var(--fg-3);
  text-align:center;background:transparent;border:0;cursor:pointer; }
.wl-phase-s:hover{ background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--fg-1) }
.wl-phase-s:focus-visible{ outline:2px solid var(--accent);outline-offset:-2px }
.wl-phase-s .mi{ font-size:15px }
.wl-phase-s.done{ color:var(--mk-ok) }
.wl-phase-s.now{ background:var(--bg-1);color:var(--accent);box-shadow:var(--mk-shadow-sm) }
/* soft gating for the owner: a phase ahead is reachable, just marked */
/* B62 wave 4 (W-07) — the chat timeline: the destinations timeline's own
   grammar, collapsed to a single bar that carries the COUNT, above the first
   message. Collapsed by default, because a thread is for reading messages;
   the history is there when you ask for it. */
.ct-tl{margin:0 0 12px;border:1px solid var(--border);border-radius:12px;background:var(--bg-2);overflow:hidden}
.ct-tl-bar{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:10px 12px;background:none;border:0;cursor:pointer;color:var(--fg-1);text-align:start}
.ct-tl-bar:hover{background:color-mix(in srgb,var(--accent) 8%,transparent)}
.ct-tl-bar .mi{font-size:18px;color:var(--accent)}
.ct-tl-l{flex:1;min-width:0;font:600 12.5px var(--mk-font-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ct-tl-n{font:700 11px/1 var(--mk-font-ui);color:var(--fg-1);background:var(--bg-3);border-radius:999px;padding:4px 8px}
.ct-tl-chev{color:var(--fg-2) !important;font-size:20px !important}
.ct-tl-body{display:none;padding:2px 12px 12px}
.ct-tl.open .ct-tl-body{display:block}
/* the timeline inside a chat is reading matter, not a form: no click affordance */
.ct-tl-body .wl-dtl{margin:0}
.ct-tl-body .wl-dtl-node{cursor:default}
.wl-phase-s.ahead{ opacity:.72 }
/* B62 wave 4 — the invitation card is addressed to YOU, so it wears the accent
   ground the rest of the roster does not; a person taken off the trip is dimmed
   but never removed, because what they already paid still counts. */
.wl-inv-me{ background:color-mix(in srgb,var(--accent) 9%,transparent);border-color:color-mix(in srgb,var(--accent) 28%,var(--border)) }
.wl-sumbox.is-off{ opacity:.62 }

.wl-stage-row{ display:flex;align-items:center;gap:10px;width:100%;min-width:0;padding:11px 12px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1);text-align:start;
  cursor:pointer;min-height:52px; }
.wl-stage-row + .wl-stage-row{ margin-top:7px }
.wl-stage-row:hover{ border-color:var(--accent) }
.wl-stage-row.is-now{ border-color:var(--accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 40%,transparent) }
/* W-07 gating — a row the group cannot act on yet still OPENS (§ M-43: never a
   dead end); it is dimmed and its slide says what it is waiting for. */
.wl-stage-row.is-waiting{ opacity:.7 }
.wl-stage-main{ flex:1;min-width:0;display:flex;flex-direction:column;gap:3px }
.wl-stage-t{ display:flex;align-items:center;gap:7px;font:700 13px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-stage-s{ font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2) }
.wl-stage-s.warn{ color:var(--mk-warning);font-weight:700 }
.wl-stage-s.ok{ color:var(--mk-ok);font-weight:700 }
.wl-stage-n{ font:800 11px/1 var(--mk-font-ui);color:var(--fg-2);padding:4px 8px;border-radius:999px;
  background:var(--bg-2);flex:0 0 auto;white-space:nowrap }
.wl-stage-go{ font-size:18px;color:var(--fg-3);flex:0 0 auto }

/* ── lodging: the stay, and its nights ─────────────────────────────────── */
.wl-lodg{ display:flex;flex-direction:column;gap:7px;width:100%;min-width:0;padding:11px 12px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1);text-align:start;cursor:pointer }
.wl-lodg + .wl-lodg{ margin-top:7px }
.wl-lodg:hover{ border-color:var(--accent) }
.wl-lodg-h{ display:flex;align-items:center;gap:9px }
.wl-lodg-nm{ flex:1;min-width:0;font:700 13px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-lodg-m{ display:flex;flex-wrap:wrap;gap:4px 8px;font:500 11.5px/1.4 var(--mk-font-ui);color:var(--fg-2) }
.wl-lodg-m .mi{ font-size:14px;vertical-align:-2px;color:var(--fg-3) }
.wl-nights{ display:flex;flex-wrap:wrap;gap:5px }
.wl-night{ flex:1 1 84px;min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:6px 3px;border-radius:9px;background:var(--bg-2);font:700 9.5px/1 var(--mk-font-ui);color:var(--fg-2) }
.wl-night .wl-av{ border-color:var(--bg-2) }
/* a night with an unclaimed bed is the trip's most actionable fact */
.wl-night.free{ background:color-mix(in srgb,var(--mk-warning) 12%,transparent);color:var(--mk-warning) }
.wl-night.over{ background:color-mix(in srgb,var(--mk-danger) 12%,transparent);color:var(--mk-danger) }

/* ── transportation: a leg ─────────────────────────────────────────────── */
.wl-leg{ display:flex;align-items:flex-start;gap:10px;width:100%;min-width:0;padding:10px 12px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1);text-align:start;cursor:pointer }
.wl-leg + .wl-leg{ margin-top:7px }
.wl-leg:hover{ border-color:var(--accent) }
.wl-leg-main{ flex:1;min-width:0;display:flex;flex-direction:column;gap:4px }
.wl-leg-t{ font:700 12.5px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.wl-leg-when{ display:flex;align-items:center;flex-wrap:wrap;gap:7px;font:600 11.5px/1.2 var(--mk-font-ui);
  color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-leg-when .mi{ font-size:14px;color:var(--fg-3) }
.wl-leg-sub{ font:500 11px/1.35 var(--mk-font-ui);color:var(--fg-2) }
/* "Marta is staying on" is an ANSWER, not a gap — it reads quiet, not alarming */
.wl-leg.none{ opacity:.82 }
.wl-leg.none .wl-ic{ background:var(--bg-2);color:var(--fg-3) }

/* ── the schedule, by day ──────────────────────────────────────────────── */
.wl-day{ margin:0 0 10px;border:1px solid var(--border);border-radius:13px;background:var(--bg-1);overflow:hidden }
.wl-day-h{ display:flex;align-items:center;gap:9px;padding:9px 12px;background:var(--bg-2) }
.wl-day-d{ font:800 12.5px/1 var(--mk-font-ui);color:var(--fg-1) }
.wl-day-w{ font:600 11px/1 var(--mk-font-ui);color:var(--fg-2);flex:1 }
.wl-day-b{ display:flex;flex-direction:column }
.wl-di{ display:flex;align-items:center;gap:9px;padding:8px 12px;border-top:1px solid var(--border);
  font:500 12px/1.3 var(--mk-font-ui);color:var(--fg-2);text-align:start;background:transparent;
  width:100%;min-width:0;cursor:pointer }
.wl-di:first-child{ border-top:0 }
.wl-di:hover{ background:var(--bg-2) }
.wl-di .mi{ font-size:16px;color:var(--fg-3);flex:0 0 auto }
.wl-di-t{ flex:1;min-width:0;color:var(--fg-1);font-weight:600 }
.wl-di-h{ font:700 11px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums;flex:0 0 auto }
/* an arrival or departure is the day's spine, so it carries the accent */
.wl-di.is-move{ background:color-mix(in srgb,var(--accent) 6%,transparent) }
.wl-di.is-move .mi{ color:var(--accent) }
/* B63-052 — an activity invited-but-not-yet-accepted: border only, no fill,
   the same accepted-vs-tentative distinction Google Calendar draws. */
.wl-di.is-tentative{ box-shadow:inset 0 0 0 1.5px var(--accent);background:transparent }
.wl-di.is-tentative .mi{ color:var(--accent) }
/* B63-052 — the Schedule slide's daily-calendar prev/next strip. */
.wl-cal-nav-row{ display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px }
.wl-cal-nav{ display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:999px;
  border:1px solid var(--border);background:var(--bg-1);color:var(--fg-2);cursor:pointer;flex:0 0 auto }
.wl-cal-nav:hover:not(:disabled){ background:var(--bg-2);color:var(--fg-1) }
.wl-cal-nav:disabled{ opacity:.35;cursor:default }
.wl-cal-nav-d{ display:flex;flex-direction:column;align-items:center;text-align:center;gap:1px }
.wl-cal-nav-d .wl-day-d{ font-size:14px }
.wl-cal-nav-d .wl-day-w{ flex:none }

/* ── B62 wave 3 · the MEAL GAME (W-21) ─────────────────────────────────────
   Pablo, on the sample: "the card game has weird styles I would like it to look
   a bit more like the content swipe game (cards and buttons)". So this block is
   deliberately tiny — the deck, the cards, the stamps, the ranking rows and the
   three buttons are content.css's own classes, mounted on a wallet slide. What
   is left is (a) what fills a poster that has no photograph, (b) the swap picker
   the plan screen opens inline, and (c) the two footer rules content declares
   for `.panel-ft` and the wallet's footer is called `.wl-panel-ft`. */
.wl-slide.cn-play-panel .ent-panel-body{ display:flex;flex-direction:column;min-height:0 }
.wl-panel-ft.mg-ft{ gap:10px;flex-wrap:wrap }
.wl-panel-ft.mg-ft:has(.cn-vbtn){ justify-content:center }
/* a recipe's art IS its field: meal type, minutes, cost per head.
   THE CASCADE, and this is UI-65's lesson a second time: content.css loads AFTER
   sections.css, so `.cn-poster{display:block}` beat `.mg-po{display:flex}` at
   equal specificity and the field rendered as one inline run in the top-left of a
   369px-tall empty tint. Doubling the class wins it without an !important. */
.mg-po.mg-po{ display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  background:linear-gradient(160deg,color-mix(in srgb,var(--accent) 22%,var(--bg-2)),color-mix(in srgb,var(--accent) 6%,var(--bg-2)));
  color:var(--fg-1) }
.mg-po .mi{ font-size:40px;color:var(--fg-1) }
.mg-po b{ font:800 11.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-2) }
.mg-po i{ font:600 11.5px/1 var(--mk-font-ui);font-style:normal;color:var(--fg-2) }
/* There is no photograph to fill, so the face is a BAND, not a 2/3 poster — the
   dish's name and ingredients sit right under it instead of below 200px of tint. */
.cn-swipe .mg-po.mg-po{ aspect-ratio:auto;height:clamp(132px,19dvh,168px);flex:0 0 auto;min-height:0;border-radius:0 }
/* the tiny face used in the ranking rows, the plan and the swap picker */
/* the tiny face used in the ranking rows, the plan and the swap picker */
.mg-po.xs.xs{ flex:0 0 auto;flex-direction:row;gap:5px;width:auto;aspect-ratio:auto;padding:7px 9px;border-radius:9px;box-shadow:none;min-height:0;height:auto }
.mg-po.xs .mi{ font-size:18px;color:var(--fg-1) }
.mg-po.xs b,.mg-po.xs i{ display:none }
.cn-res-row .cn-tie-main{ flex:1;min-width:0 }
/* the day badge is a date, not prose — it never wraps mid-date */
.cn-res-row .cn-res-rank{ white-space:nowrap;flex:0 0 auto }
.cn-res-row.is-kept{ background:var(--bg-2) }
.mg-swap{ flex:0 0 auto }
/* the alternatives for one slot, opened under its row rather than in another
   layer (§ M-88 — a picker is not worth a floor of its own) */
.mg-alts{ display:flex;flex-direction:column;gap:5px;margin:2px 0 8px;padding:8px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-2) }
.mg-alt{ display:flex;align-items:center;gap:9px;padding:6px 8px;border:1px solid var(--border);
  border-radius:10px;background:var(--bg-1);cursor:pointer;text-align:start;width:100%;min-width:0 }
.mg-alt:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mg-alts-cur{ display:flex;align-items:center;gap:6px;padding:2px 2px 6px;font:600 11.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
.mg-alts-cur .mi{ font-size:15px;color:var(--accent) }
.mg-alts-cur b{ color:var(--fg-1) }
.mg-alt .cn-tie-main b{ font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.mg-alt .cn-tie-main span{ font:500 11px/1.2 var(--mk-font-ui);color:var(--fg-2) }

/* ── where everyone stands ─────────────────────────────────────────────── */
.wl-bal{ border:1px solid var(--border);border-radius:13px;background:var(--bg-1);overflow:hidden }
.wl-bal-r{ display:flex;align-items:center;gap:9px;padding:9px 12px;border-bottom:1px solid var(--border) }
.wl-bal-r:last-child{ border-bottom:0 }
.wl-bal-nm{ flex:1;min-width:0;font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-bal-st{ font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-2);white-space:nowrap }
.wl-tent{ display:flex;align-items:flex-start;gap:7px;margin-top:8px;font:500 11.5px/1.4 var(--mk-font-ui);color:var(--fg-2) }
.wl-tent .mi{ font-size:15px;color:var(--fg-3);flex:0 0 auto }
.wl-vote{ display:inline-flex;align-items:center;gap:4px;font:700 10.5px/1 var(--mk-font-ui);
  padding:3px 8px;border-radius:999px;background:var(--bg-2);color:var(--fg-2) }
.wl-vote.opt{ background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent) }
/* a per-item approval row in the close-out */
.wl-appr{ display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:6px }
.wl-appr .wl-chip{ min-height:32px }

/* ═══ B62 wave 5 (W-30) — CONTRACTS on Wallet ▸ Balance ═══════════════════
   The card IS `.wl-pmc` (the account card) and the slides ARE `.wl-sech` +
   `.wl-kv` + `.wl-sumbox`. What is below is only the handful of things the
   wallet had no answer for:
     • a mark PAIR (a contract has two parties, an account has one issuer),
     • a COMPOSITION bar — an amount made of parts that sum to it,
     • the payment ledger's two-dates-a-month rows, the weighted-ops table and
       the tier table.
   Every class is `.wl-ctc-*` so nothing here can reach an account card, and
   the two rules that override `.wl-pmc` geometry double their class to win on
   specificity rather than on source order (the UI-65 lesson, twice paid for). */
.wl-ctc-pair.wl-ctc-pair{ width:auto;display:flex;align-items:center }
.wl-ctc-pair .wl-pmc-mk + .wl-pmc-mk{ margin-inline-start:-13px;box-shadow:inset 0 0 0 1px var(--bd-1,var(--border)),0 0 0 2px var(--bg-1,#fff) }
.wl-ctc .wl-pmc-chips{ align-items:center }
/* the composition bar: segments, not a percentage — the widths ARE the money */
/* B63-044 — the contract card's secondary-information row: an age chip
   (blank when nothing is aging) and the monthly/frequent figure, both
   plain-weight so neither reads as a second claim on the money above. */
.wl-ctc-sec{ display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px;font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-3) }
.wl-ctc-age{ display:inline-flex;align-items:center;gap:4px }
.wl-ctc-age.warn{ color:var(--danger,#B3261E) }
.wl-ctc-age .mi, .wl-ctc-sec-amt .mi{ font-size:14px }
.wl-ctc-sec-amt{ display:inline-flex;align-items:center;gap:4px;font-variant-numeric:tabular-nums }
.wl-ctc-bar{ display:flex;height:8px;border-radius:999px;overflow:hidden;background:var(--bg-2,#eef1f4) }
.wl-ctc-bar > span{ display:block;height:100% }
.wl-ctc-bar > .a{ background:var(--accent) }
.wl-ctc-bar > .b{ background:var(--warn,#8A6100) }
.wl-ctc-bar > .c{ background:var(--mk-ok,#157F4C) }
.wl-ctc-bar > .d{ background:var(--mk-debt,#FF4D8D) }
.wl-ctc-leg{ display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px }
.wl-ctc-lg{ display:inline-flex;align-items:center;gap:6px;font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-ctc-lg b{ color:var(--fg-1);font-weight:700 }
.wl-ctc-lg i{ width:9px;height:9px;border-radius:3px;flex:0 0 auto }
.wl-ctc-lg i.a{ background:var(--accent) } .wl-ctc-lg i.b{ background:var(--warn,#8A6100) }
.wl-ctc-lg i.c{ background:var(--mk-ok,#157F4C) } .wl-ctc-lg i.d{ background:var(--mk-debt,#FF4D8D) }
/* the panel's summary block */
.wl-ctc-hd{ padding:12px 13px;border:1px solid var(--border);border-radius:14px;background:var(--bg-1);margin-bottom:10px }
.wl-ctc-hd-t{ display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:8px }
.wl-ctc-hd-since{ font:600 11.5px/1.2 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-ctc-hd-v{ display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font:800 26px/1.05 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;margin-bottom:10px }
.wl-ctc-hd-v.neg{ color:var(--mk-danger,#C81E1E) } .wl-ctc-hd-v.pos{ color:var(--mk-ok,#157F4C) }
.wl-ctc-hd-u{ font:600 11.5px/1 var(--mk-font-ui);color:var(--fg-2) }
.wl-ctc-rows{ display:flex;flex-direction:column;gap:7px;margin-top:10px }
.wl-ctc-row{ cursor:pointer;min-height:52px;text-align:start }
.wl-ctc-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
/* B63-087 — a "go" chevron must center on the box's full height even when its
   row sets `align-items:flex-start` (Menu's rows do, so a wrapped subtitle
   doesn't stretch the icon) — align-self overrides that per-item. */
.wl-ctc-go{ flex:0 0 auto;font-size:18px;color:var(--fg-3);align-self:center }
.wl-sumbox-s.warn{ color:var(--mk-danger,#C81E1E);font-weight:600 }
/* the month, day by day */
.wl-ctc-days{ display:flex;flex-direction:column;border:1px solid var(--border);border-radius:12px;overflow:hidden }
.wl-ctc-day{ display:flex;align-items:center;gap:9px;padding:8px 11px;border-bottom:1px solid var(--border);
  font:600 12px/1.3 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wl-ctc-day:last-child{ border-bottom:0 }
.wl-ctc-day .mi{ font-size:16px;color:var(--mk-ok,#157F4C);flex:0 0 auto }
.wl-ctc-day.ahead .mi{ color:var(--fg-3) }
.wl-ctc-day.off .mi{ color:var(--mk-danger,#C81E1E) }
.wl-ctc-day-d{ flex:1;min-width:0 }
.wl-ctc-day-v{ flex:0 0 auto;font-weight:700 }
.wl-ctc-day.off .wl-ctc-day-v{ font:500 11.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
.wl-ctc-day.ahead .wl-ctc-day-d,.wl-ctc-day.ahead .wl-ctc-day-v{ color:var(--fg-2) }
/* a total line is a statement, so it is heavier than the rows above it */
.wl-kv.wl-ctc-total{ margin-top:4px;border-top:2px solid var(--border);border-bottom:0;padding-top:10px }
.wl-kv.wl-ctc-total .wl-kv-k{ font-weight:700;color:var(--fg-1) }
.wl-kv.wl-ctc-total .wl-kv-v{ font:800 15px/1.2 var(--mk-font-ui);color:var(--fg-1) }
/* the payment ledger: one block per month, two streams inside it */
.wl-ctc-per{ border:1px solid var(--border);border-radius:12px;background:var(--bg-1);margin-bottom:8px;overflow:hidden }
.wl-ctc-per.now{ border-color:color-mix(in srgb,var(--accent) 55%,var(--border)) }
.wl-ctc-per-h{ display:flex;align-items:center;gap:8px;padding:8px 11px;background:var(--bg-2);border-bottom:1px solid var(--border) }
.wl-ctc-per-m{ flex:1;min-width:0;font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-ctc-per-v{ font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wl-ctc-prow{ display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:9px 11px;border-bottom:1px solid var(--border) }
.wl-ctc-prow:last-child{ border-bottom:0 }
.wl-ctc-prow > .mi{ font-size:17px;color:var(--fg-2);flex:0 0 auto }
.wl-ctc-prow-m{ flex:1 1 40%;min-width:120px;display:flex;flex-direction:column;gap:2px }
.wl-ctc-prow-t{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-ctc-prow-s{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-ctc-prow-v{ font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wl-ctc-prow-st{ display:inline-flex;align-items:center;gap:4px;font:700 10.5px/1 var(--mk-font-ui);
  padding:4px 9px;border-radius:999px;background:var(--bg-2);color:var(--fg-2);flex:0 0 auto }
.wl-ctc-prow-st .mi{ font-size:13px }
/* FIFTH APPEARANCE of accent-ink-on-accent-tint in B62 (wave 3's icon, § S-24's
   picked step, .wl-ctc-ent, and both of these). Green ink on a 14% tint of the
   same green measured 4.17:1 in LIGHT theme at 10.5px, on 30 pills across the
   contract ledger, the subsidiaries slide and the whole Stock inventory. The
   rule is settled: THE TINT CARRIES THE SEMANTIC COLOUR, THE INK IS ORDINARY
   TEXT — the glyph keeps the hue, so the pill still reads green or red at a
   glance without staking legibility on it. */
.wl-ctc-prow-st.ok{ background:color-mix(in srgb,var(--mk-ok,#157F4C) 14%,transparent);color:var(--fg-1) }
.wl-ctc-prow-st.ok .mi{ color:var(--mk-ok,#157F4C) }
.wl-ctc-prow-st.warn{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 13%,transparent);color:var(--fg-1) }
.wl-ctc-prow-st.warn .mi{ color:var(--mk-danger,#C81E1E) }
.wl-ctc-prov-v,.wl-ctc-svc-v{ flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:2px;
  font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
/* the entities a hired service needs */
.wl-ctc-ents{ display:flex;flex-wrap:wrap;gap:4px;margin-top:4px }
/* The tint carries the accent, the INK is ordinary text. Accent-on-accent-tint
   measured 1.35:1 here — the fourth appearance of that defect class in this
   batch (wave 3's icon, § S-24's picked step, UI's quiet ink). */
.wl-ctc-ent{ font:600 10px/1 var(--mk-font-ui);padding:4px 7px;border-radius:6px;
  background:color-mix(in srgb,var(--accent) 11%,transparent);color:var(--fg-1) }
.wl-ctc-scope{ margin-bottom:8px }
/* creations · reads · updates · deletions, weighted into one number */
.wl-ctc-ops{ display:flex;flex-direction:column;gap:7px;margin:8px 0 4px }
.wl-ctc-op{ display:grid;grid-template-columns:minmax(74px,1fr) auto auto;align-items:center;gap:4px 9px }
.wl-ctc-op-k{ font:700 11.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-ctc-op-n{ font:600 11.5px/1.2 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-ctc-op-w{ font:600 11px/1.2 var(--mk-font-ui);color:var(--fg-2) }
.wl-ctc-op-bar{ grid-column:1/3;height:6px }
.wl-ctc-op-v{ font:700 11.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;text-align:end }
/* the tier table — the band you are in is stated, the others stay readable */
.wl-ctc-tiers{ display:flex;flex-direction:column;border:1px solid var(--border);border-radius:12px;overflow:hidden;margin-bottom:9px }
.wl-ctc-tier{ display:flex;align-items:center;gap:9px;padding:9px 11px;border-bottom:1px solid var(--border) }
.wl-ctc-tier:last-child{ border-bottom:0 }
.wl-ctc-tier > .mi{ font-size:17px;color:var(--fg-3);flex:0 0 auto }
.wl-ctc-tier.on{ background:color-mix(in srgb,var(--accent) 9%,transparent) }
.wl-ctc-tier.on > .mi{ color:var(--accent) }
.wl-ctc-tier-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px }
.wl-ctc-tier-t{ font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.wl-ctc-tier.on .wl-ctc-tier-t{ font-weight:800 }
.wl-ctc-tier-s{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.wl-ctc-tier-v{ flex:0 0 auto;font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wl-ctc-party .wl-pmc-mk{ flex:0 0 auto }
/* a rule and its parts: the number sits in the sentence, the explanation below */
.wl-ctc-note-sub{ display:block;margin-top:3px;font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-2) }
.wl-ctc-od{ color:var(--mk-danger,#C81E1E) }
@media (pointer:coarse){ .wl-ctc-row{ min-height:56px } }
/* B62 wave 5 — the wallet's Pay / Nudge action (and the contract's "mark as
   filed") is 27px tall: fine under a mouse, below the touch floor under a
   finger, on EVERY debt row in the app. Keyed on the WIDTH BAND as well as the
   pointer: `pointer:coarse` alone leaves a 390px browser window — which is
   where the phone reading is actually done — at 27px, so the defect stays
   invisible in exactly the place it gets checked. Desktop is untouched. */
@media (pointer:coarse),(max-width:640px){ .wl-debt-btn{ min-height:44px;padding-inline:14px } }

/* ═══ § M-43 · THE PANEL FORM FLOOR — APP-WIDE ══════════════════════
   Found while probing § S-16 Suite's cell editor on a phone, and it was never a
   Suite defect: `.ent-input` has NO touch floor anywhere. Only `.pe-body
   .ent-input` was ever raised (the entity form), so every OTHER form in the app
   that lives on the panel floor — Ledger's transaction, Trips, Companies,
   Groceries, Catalog, Menu, Stock, Drive, Support's case, Canvas's rename,
   Flowcharts', Suite's run and cell editors — rendered its fields at 35px on a
   phone. Eight sections' worth of forms, under the bar, in the one place § M-43
   says a user must be able to do everything.

   Fixed at the ROOT rather than per section: a per-selector fix on a shared
   floor never converges (the `--fg-3` lesson, and the seventh specificity
   correction in B62). `[data-wl-body]` is the panel body every one of those
   forms is built into, and the element-qualified selector out-specifies both
   `.ent-input` and `.ent-input.sm`. The two deliberate exceptions stay small:
   a filter row and an explicitly-compact `.sm` field inside a dense grid. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  [data-wl-body] input.ent-input,[data-wl-body] select.ent-input,
  [data-wl-body] textarea.ent-input,[data-wl-body] .ent-input:not(input):not(select):not(textarea){
    min-height:44px }
  [data-wl-body] textarea.ent-input{ min-height:74px }
  /* the panel's own footer verbs sit on the same floor */
  [data-wl-ft] button,[data-wl-ft] .wl-chip,[data-wl-ft] .wl-close-btn{ min-height:44px }
}

/* ═══ B62 § S-11 — COMPANIES ═══════════════════════════════════════
   The company card IS the account card and the ownership bar IS the contract's
   composition bar — "one whole made of stated parts" is the same sentence in
   both places. Only what Companies genuinely adds lives here. */
.wl-co-flag{ font-size:14px;line-height:1 }
.wl-co-flag.lg{ font-size:22px;line-height:1;flex:0 0 auto;width:26px;text-align:center }
/* B63 W7 (068) — real flag image (flagcdn), replacing the emoji glyph. */
.wl-co-flag-img{ width:16px;height:12px;object-fit:cover;border-radius:2px;flex:0 0 auto }
.wl-co-hd-t{ display:flex;align-items:flex-start;gap:11px;margin-bottom:9px }
.wl-co-mk-lg.wl-co-mk-lg{ width:46px;height:46px;border-radius:12px }
.wl-co-mk-lg .wl-logo,.wl-co-mk-lg img{ width:100%;height:100%;object-fit:contain }
.wl-co-hd-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:3px }
.wl-co-hd-nm{ font:800 15px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.wl-co-hd-s{ font:500 11.5px/1.45 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty }
.wl-co-hd .wl-pmc-chips{ margin-bottom:10px }
.wl-co-pct{ flex:0 0 auto;font:800 14px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wl-co-inst{ align-items:center }
/* the marks, shown as what they are — artwork, on a checkered-free plate that
   does not pretend to be a colour */
.wl-co-marks{ display:flex;flex-wrap:wrap;gap:10px;margin:8px 0 4px }
.wl-co-mark{ display:flex;flex-direction:column;align-items:center;gap:5px;flex:0 0 auto }
.wl-co-mark-box{ width:64px;height:64px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1);
  display:grid;place-items:center;padding:9px }
.wl-co-mark-box img{ max-width:100%;max-height:100%;object-fit:contain }
.wl-co-mark-k{ font:600 10.5px/1.2 var(--mk-font-ui);color:var(--fg-2);text-align:center;max-width:74px }
.wl-co-ctr{ cursor:pointer }
.wl-co-ctr:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }

/* ═══ B62 § S-24 — GROCERIES ══════════════════════════════════════
   A shopping list has to be usable with a thumb in a shop, so the row is a
   `.wl-sumbox` with exactly two controls: the mark (left, big) and the ladder
   (right). The LADDER's own geometry is the only new thing. */
.gr-row{ align-items:center;cursor:pointer }
.gr-row.is-got{ opacity:.72 }
.gr-row.is-got .wl-sumbox-t{ text-decoration:line-through;text-decoration-color:var(--fg-3) }
.gr-row.is-stuck{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 38%,var(--border)) }
.gr-check{ flex:0 0 auto;appearance:none;border:0;background:transparent;cursor:pointer;padding:0;
  width:40px;height:40px;display:grid;place-items:center;border-radius:12px;color:var(--fg-3) }
.gr-check:hover{ background:var(--bg-2) }
.gr-check .mi{ font-size:26px }
.gr-row.is-got .gr-check{ color:var(--mk-ok,#157F4C) }
.gr-pres{ font-weight:700;color:var(--fg-1) }
.gr-any{ font-style:italic;color:var(--fg-2) }
.gr-fallback{ display:block;margin-top:2px;color:var(--fg-2) }
.gr-stuck{ color:var(--mk-danger,#C81E1E);font-weight:600 }
.gr-steps{ flex:0 0 auto;display:flex;align-items:center;gap:4px;min-width:44px;min-height:40px;
  padding:0 9px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1);
  color:var(--fg-2);cursor:pointer;justify-content:center }
.gr-steps:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border));color:var(--accent-text,var(--accent)) }
.gr-steps-n{ font:800 12.5px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums }
.gr-steps .mi{ font-size:17px }
/* B63 W4 (015/080) — the ladder is now DRAGGED to rank, not stepped with
   up/down buttons: `.pref-row` is deliberately the same shape as View ▸
   Sort's `.sort-row` (drag handle implicit on the whole row, numbered
   ordinal, a single remove), so a reader who has ranked a Sort already knows
   this. And a restrictive rule (a locked brand) sits above the ladder, once,
   because it isn't a rank — it's a gate every rank still has to pass. */
.gr-restrict{ display:flex;align-items:center;gap:10px;padding:9px 11px;border:1px solid var(--border);
  border-radius:12px;background:var(--bg-1);margin-bottom:10px }
.gr-restrict.is-on{ border-color:color-mix(in srgb,var(--accent) 40%,var(--border));background:var(--accent-soft) }
.pref-restrict-btn, .pref-restrict-rm{ flex:0 0 auto;cursor:pointer }
.pref-restrict-list{ display:flex;flex-direction:column;gap:6px }
.pref-restrict-opt{ display:flex;align-items:center;gap:9px;cursor:pointer;text-align:start;width:100% }
.pref-restrict-opt .mi{ flex:0 0 auto;font-size:19px;color:var(--fg-3) }
.pref-restrict-opt.is-sel .mi{ color:var(--accent-text,var(--accent)) }
.pref-restrict-opt.is-sel{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border));background:var(--accent-soft) }
.pref-list{ display:flex;flex-direction:column;gap:6px;margin-bottom:6px }
.pref-row{ display:flex;align-items:center;gap:10px;padding:9px 11px;border:1px solid var(--border);
  border-radius:12px;background:var(--bg-1);cursor:grab }
.pref-row.is-pick{ background:color-mix(in srgb,var(--accent) 10%,transparent) }
.pref-row.is-out .wl-sumbox-t{ color:var(--fg-2) }
.pref-row.is-pick .wl-sumbox-s{ color:var(--fg-1);font-weight:700 }
.pref-row.dragging{ opacity:.45 }
.pref-row.drop-before{ box-shadow:inset 0 2px 0 var(--accent) }
.pref-row.drop-after{ box-shadow:inset 0 -2px 0 var(--accent) }
.pref-ord{ flex:0 0 auto;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font:800 11px/1 var(--mk-font-ui);background:var(--bg-2);color:var(--fg-2) }
.pref-row.is-pick .pref-ord{ background:var(--accent);color:#fff }
/* Audit A15 — the rank number is the drag grip (sortable.js): a real button,
   a larger hit area on touch, no scroll while dragging. */
button.pref-ord{ border:0;padding:0;cursor:grab;touch-action:none;box-shadow:0 0 0 6px transparent; }
button.pref-ord:active{ cursor:grabbing; }
button.pref-ord:focus-visible{ outline:2px solid var(--accent);outline-offset:2px; }
.pref-row.drop-before{ box-shadow:0 -2px 0 var(--accent); }
.pref-row.drop-after{ box-shadow:0 2px 0 var(--accent); }
@media (pointer:coarse){ button.pref-ord{ width:32px;height:32px;font-size:12px; } }
.mn-ing.is-pref{ cursor:pointer; }
.mn-pref-reset{ align-self:flex-start; }
.mn-ing.is-pref:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)); }
.mn-ing.is-pref:focus-visible{ outline:2px solid var(--accent);outline-offset:2px; }
.pref-rm{ flex:0 0 auto;appearance:none;border:1px solid var(--border);background:var(--bg-1);border-radius:9px;
  width:30px;height:30px;display:grid;place-items:center;cursor:pointer;color:var(--fg-2) }
.pref-rm:hover:not(:disabled){ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 45%,var(--border));color:var(--mk-danger,#C81E1E) }
.pref-rm:disabled{ opacity:.38;cursor:default }
.pref-rm .mi{ font-size:17px }
.gr-add{ display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 4px }
.gr-addb{ cursor:pointer }
@media (pointer:coarse),(max-width:640px){
  .pref-rm{ width:40px;height:40px }
  .gr-check{ width:44px;height:44px }
  .gr-steps{ min-height:44px }
}

/* ═══ B62 § S-29 — SHOP ▸ CATALOG ═════════════════════════════════
   The category TREE borrows the entity/route tree's grammar (a twist, an icon,
   nested children indented by depth) because that is how this app already says
   "this contains that" — and § S-55 will ask for the same shape on Roles.
   Indentation is a custom property so depth has no ceiling: his own example is
   four levels and he said "multiple levels". */
.ct-tree{ display:flex;flex-direction:column;gap:5px }
.ct-node{ display:flex;flex-direction:column;gap:5px }
.ct-row{ display:flex;align-items:center;gap:9px;cursor:pointer;
  margin-inline-start:calc(var(--ct-d,0) * 18px);
  padding:9px 11px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1);min-height:48px }
.ct-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.ct-twist{ flex:0 0 auto;font-size:19px;color:var(--fg-2) }
.ct-twist.is-leaf{ color:var(--fg-4,var(--fg-3));font-size:15px }
.ct-row-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px }
.ct-row-t{ font:700 12.5px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.ct-row-s{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.ct-kids{ display:flex;flex-direction:column;gap:5px }
.ct-count{ flex:0 0 auto;font:700 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;
  display:flex;flex-direction:column;align-items:flex-end;gap:1px;text-align:end }
.ct-allergen{ display:inline-flex;align-items:center;gap:3px;font:700 10px/1 var(--mk-font-ui);
  padding:3px 7px;border-radius:6px;vertical-align:middle;
  background:color-mix(in srgb,var(--mk-danger,#C81E1E) 13%,transparent);color:var(--mk-danger,#C81E1E) }
.ct-allergen .mi{ font-size:12px }

/* ═══ B63 W3 — SHOP: Catalog · Brands · Stock ═══════════════════════════
   One tree (the `.ct-row` boxes above), one record link (`.sh-item`), one
   brand mark. The row's padding is declared HERE on `.sh-row` as well, so no
   later sheet can quietly strip it again (093/126). Icon buttons are square
   by construction — width = height, aspect-ratio 1 (097/126). */
.sh-tree{ gap:6px }
.sh-tree .ct-node, .sh-tree .ct-kids{ gap:6px }
.ct-row.sh-row{ gap:10px;padding:8px 10px 8px 8px }
.ct-row.sh-row:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.ct-row.sh-row.is-out{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 32%,var(--border)) }
.ct-row.sh-row.is-out .st-qty{ color:var(--mk-danger,#C81E1E) }
.sh-twist{ flex:0 0 auto;width:30px;height:30px;aspect-ratio:1;display:grid;place-items:center;padding:0;
  border:0;border-radius:8px;background:transparent;color:var(--fg-2);cursor:pointer }
.sh-twist .mi{ font-size:20px;line-height:1 }
.sh-twist:not(.is-leaf):hover{ background:var(--bg-2);color:var(--fg-1) }
.sh-twist.is-leaf{ cursor:inherit }
[dir="rtl"] .sh-twist .mi{ transform:scaleX(-1) }
.sh-mark{ flex:0 0 auto;width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-text,var(--accent)) }
.sh-mark .mi{ font-size:18px }
.sh-act{ flex:0 0 auto;width:32px;height:32px;aspect-ratio:1;display:grid;place-items:center;padding:0;
  border:1px solid var(--border);border-radius:9px;background:var(--bg-1);color:var(--fg-1);cursor:pointer }
.sh-act .mi{ font-size:19px;line-height:1 }
.sh-act:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border));color:var(--accent-text,var(--accent)) }
.sh-price{ min-width:64px }
/* a brand: its logo when attached, its monogram on its own hue until then */
.sh-bmark{ flex:0 0 auto;width:40px;height:40px;border-radius:10px;display:grid;place-items:center;overflow:hidden;
  font:800 13px/1 var(--mk-font-ui);letter-spacing:.02em;
  background:oklch(.93 .07 var(--sh-h,200));color:oklch(.36 .13 var(--sh-h,200)) }
[data-theme="dark"] .sh-bmark{ background:oklch(.32 .07 var(--sh-h,200));color:oklch(.9 .08 var(--sh-h,200)) }
.sh-bmark.sm{ width:32px;height:32px;border-radius:9px;font-size:11px }
.sh-bmark.lg{ width:56px;height:56px;border-radius:14px;font-size:18px }
.sh-bmark.has-logo, [data-theme="dark"] .sh-bmark.has-logo{ background:#fff;border:1px solid var(--border) }
.sh-bmark img{ width:100%;height:100%;object-fit:contain;padding:12%;box-sizing:border-box }
.sh-bmark.is-none, [data-theme="dark"] .sh-bmark.is-none{ background:var(--bg-2);color:var(--fg-3) }
.sh-bmark .mi{ font-size:18px }
.sh-brand-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:8px }
.wl-sumbox.sh-brand, .wl-sumbox.sh-item{ cursor:pointer;align-items:center }
.wl-sumbox.sh-brand:hover, .wl-sumbox.sh-item:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.wl-sumbox.sh-brand:focus-visible, .wl-sumbox.sh-item:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.wl-sumbox.sh-item + .wl-sumbox.sh-item{ margin-top:6px }
/* inside a record panel */
.sh-link{ color:var(--accent-text,var(--accent));cursor:pointer;text-decoration:none;font-weight:700 }
.sh-link:hover{ text-decoration:underline }
.sh-inline-acts{ display:flex;flex-wrap:wrap;gap:6px;margin:8px 0 4px }
.sh-sku-hd{ display:flex;align-items:center;gap:12px;margin:0 0 12px }
.sh-sku-hd-m{ display:flex;flex-direction:column;gap:3px;min-width:0 }
.sh-sku-t{ font:700 15px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.sh-sku-s{ font:600 12.5px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.sh-line-hd{ display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 12px }
.sh-line-hd .st-qty{ font-size:22px }
.sh-mono{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;letter-spacing:.02em }
.sh-para{ margin:4px 0 8px;font:500 12.5px/1.5 var(--mk-font-ui);color:var(--fg-1) }
.sh-bodies{ display:flex;flex-wrap:wrap;gap:4px;justify-content:flex-end }
.sh-body{ display:inline-flex;align-items:center;gap:3px;padding:3px 7px;border-radius:6px;background:var(--bg-2);
  font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-2) }
.sh-body .mi{ font-size:13px }
/* the edit form */
.sh-form{ display:flex;flex-direction:column;gap:12px }
.sh-seg{ align-self:flex-start }
.sh-icons{ display:grid;grid-template-columns:repeat(auto-fill,minmax(38px,1fr));gap:6px }
.sh-ic{ aspect-ratio:1;display:grid;place-items:center;padding:0;border:1px solid var(--border);border-radius:9px;
  background:var(--bg-1);color:var(--fg-2);cursor:pointer }
.sh-ic .mi{ font-size:19px }
.sh-ic.on{ border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text,var(--accent)) }
.sh-pres > span, .sh-nut-grid > span{ display:flex;flex-direction:column;gap:5px;min-width:0 }
.sh-pres label, .sh-nut-grid label{ font:700 11.5px/1 var(--mk-font-ui);color:var(--fg-2);letter-spacing:.05em }
.sh-nut-grid{ display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px }
.sh-ta{ height:auto;min-height:76px;padding:8px 10px;resize:vertical;font:500 13px/1.45 var(--mk-font-ui) }
.sh-ck{ display:flex;align-items:center;gap:8px;min-height:40px }
.sh-danger{ margin-top:18px;padding-top:14px;border-top:1px solid var(--border);display:flex }
.sh-logo-ed{ display:flex;align-items:center;gap:12px }
.sh-logo-acts{ display:flex;flex-wrap:wrap;gap:6px }
.sh-file{ cursor:pointer }
@media (pointer:coarse),(max-width:640px){
  .ct-row{ min-height:52px;margin-inline-start:calc(var(--ct-d,0) * 12px) }
  .sh-twist, .sh-act{ width:44px;height:44px }
  /* a leaf has nothing to expand, so on a phone it gives its twist slot back */
  .sh-twist.is-leaf{ display:none }
  .sh-code{ display:none }
  .sh-nut-grid{ grid-template-columns:repeat(2,minmax(0,1fr)) }
  .sh-brand-grid{ grid-template-columns:1fr }
}

/* ═══ B62 § S-29 — SHOP ▸ MENU ═══════════════════════════════════════════
   Catalog's vocabulary again (he said sections nest "similar to Catalog
   categories", so they ARE that tree) plus § S-24's ladder steps inside an
   ingredient row. What is new: the amount column, the tags, the reason a dish
   is down, and the meal's parts. */
.mn-row{ cursor:pointer;align-items:flex-start }
.mn-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-row.is-out,.mn-dish.is-out,.mn-ing.is-out,.mn-part.is-out{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 36%,var(--border)) }
.mn-ing{ align-items:flex-start }
.mn-ing.is-opt{ border-style:dashed }
.mn-qty{ flex:0 0 auto;min-width:56px;font:800 12.5px/1.3 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.mn-tag{ display:inline-flex;align-items:center;gap:3px;font:700 10px/1 var(--mk-font-ui);padding:3px 7px;border-radius:6px;
  background:var(--bg-2);color:var(--fg-2);vertical-align:middle }
.mn-tag .mi{ font-size:12px }
.mn-tag.ok{ background:color-mix(in srgb,var(--mk-ok,#157F4C) 14%,transparent);color:var(--mk-ok,#157F4C) }
.mn-tag.dislike{ background:color-mix(in srgb,var(--warn,#8A6100) 15%,transparent);color:var(--fg-1) }
/* the ladder, in miniature: the step in use is the loud one */
.mn-ladder{ display:flex;flex-wrap:wrap;gap:4px;margin-top:5px }
.mn-lstep{ font:600 10px/1.2 var(--mk-font-ui);padding:3px 7px;border-radius:6px;background:var(--bg-2);color:var(--fg-2) }
.mn-lstep.on{ background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--fg-1);font-weight:800 }
.mn-why{ color:var(--mk-danger,#C81E1E);font-weight:600 }
.mn-flags{ display:flex;flex-wrap:wrap;gap:4px;margin-top:5px }
.mn-price{ flex:0 0 auto;font:800 13.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.mn-sec{ margin-inline-start:calc(var(--ct-d,0) * 14px);margin-bottom:10px }
.mn-sec-h{ display:flex;align-items:center;gap:7px;margin:6px 0;font:800 12px/1.3 var(--mk-font-ui);
  color:var(--fg-2);text-transform:uppercase;letter-spacing:.04em }
.mn-sec-h .mi{ font-size:16px }
.mn-dish{ cursor:pointer;align-items:flex-start }
.mn-dish:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-part{ cursor:pointer;align-items:center }
.wl-note-row.is-warn{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 34%,var(--border)) }
.wl-note-row.is-warn .mi{ color:var(--mk-danger,#C81E1E) }
/* B63 W4 — a recipe leaf inside the section tree (082), and a preparation's
   ordered timeline (086): each step numbered, an instruction step reads as
   plain text, a nested-preparation step opens like any other prep box. */
.mn-recipe-leaf{ cursor:pointer }
.mn-recipe-leaf:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-prep-jump{ cursor:pointer;align-items:center;gap:9px }
.mn-prep-jump:hover{ background:var(--bg-2) }
.mn-timeline{ display:flex;flex-direction:column;gap:6px;margin-bottom:8px }
.mn-step{ display:flex;align-items:flex-start;gap:10px;padding:9px 11px;border:1px solid var(--border);
  border-radius:12px;background:var(--bg-1) }
.mn-step.is-nested{ cursor:pointer }
.mn-step.is-nested:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-step.is-instr{ align-items:center;background:var(--bg-2);border-style:dashed }
.mn-step-n{ flex:0 0 auto;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font:800 11px/1 var(--mk-font-ui);background:var(--bg-2);color:var(--fg-2) }
.mn-step.is-instr .mn-step-n{ background:transparent;border:1px dashed var(--border) }
@media (pointer:coarse),(max-width:640px){
  .mn-row,.mn-dish,.mn-recipe-leaf,.mn-prep-jump{ min-height:56px }
  .mn-sec{ margin-inline-start:calc(var(--ct-d,0) * 8px) }
}

/* ═══ B62 § S-29 — SHOP ▸ STOCK ══════════════════════════════════════════
   Everything here is Menu's and Catalog's vocabulary; the only new thing is
   the count column, because a quantity read on a phone in a cellar has to be
   the first thing the eye lands on. */
.st-loc{ cursor:pointer;align-items:flex-start }
.st-loc:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.st-line{ align-items:center }
.st-line.is-out{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 36%,var(--border)) }
.st-qty{ flex:0 0 auto;min-width:64px;font:800 15px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.st-line.is-out .st-qty{ color:var(--mk-danger,#C81E1E) }
.st-group{ margin-bottom:12px }
.st-group-n{ margin-inline-start:auto;font:700 11px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.mn-sec-h{ align-items:center }

/* ═══ B62 § S-03 — DRIVE ═════════════════════════════════════════
   His four divisions are FILTER OPTIONS, not tabs, so the switch is the app's
   own `.seg` — with one change: five options with counts cannot fit one phone
   row, and § M-43 says nothing may be cropped, so this one WRAPS (and is a
   rounded rect rather than a pill, because a wrapped pill reads as a bug).
   The rest of the section is new CSS only where the app had no answer: a
   preview box per file type, a waveform, a paper page, a transport. */
/* B63-070/071 — a single row that never wraps: once the nine filters don't
   fit, it scrolls horizontally instead (same recipe as `.map-layer-seg`).
   `.dr-switch-pinned` (set by `drSyncBar()`) makes the whole switch sticky
   right under the page header, at the header's measured height, wearing the
   header's own glass band so content passing under it stays readable. */
.dr-seg{ flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;border-radius:14px;max-width:100% }
.dr-seg::-webkit-scrollbar{ display:none }
.dr-seg button{ display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;white-space:nowrap }
.dr-seg button .mi{ font-size:16px }
.dr-seg-n{ font:800 10.5px/1 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums;
  background:var(--bg-2);border-radius:var(--mk-radius-pill);padding:3px 6px }
.dr-seg button.on .dr-seg-n{ background:var(--accent-soft);color:var(--accent-text) }
/* Positioning only — the glass band itself is the ONE shared definition in
   shell.css (`.page-h::before` / `.sec-tabs.sec-tabs-inpage::before`), which
   this selector list now includes. Do not re-add a blur here. */
.page-view[data-view="drive"] [data-dr-switch].dr-switch-pinned{
  /* Cancels `.page`'s 18px row-gap so the switch sits flush under the header
     (same recipe as `.sec-tabs.sec-tabs-inpage`) — that gap read as "too much
     space between the header and the bar" on tablet/mobile portrait (070). */
  position:sticky;z-index:19;margin:-18px 0 12px;padding-block:6px;background:transparent }
.page-view[data-view="drive"] [data-dr-switch].dr-switch-pinned > *{ position:relative;z-index:1 }
/* ── B63-075 — the folder breadcrumb, same grammar as the workshop/suite
   back-bars (`.wk-bar`/`.su-bar`): a Back chip + clickable crumbs. */
.dr-crumb{ display:flex;align-items:center;gap:4px;flex-wrap:wrap;margin-bottom:12px }
.dr-crumb-sep{ font-size:16px;color:var(--fg-3) }
.dr-crumb-b{ appearance:none;border:0;background:transparent;cursor:pointer;border-radius:8px;
  padding:5px 8px;font:600 12.5px var(--mk-font-ui);color:var(--fg-2) }
.dr-crumb-b:hover{ background:var(--bg-2);color:var(--fg-1) }
.dr-crumb-b.is-cur{ color:var(--fg-1);cursor:default }
.dr-crumb-b.is-cur:hover{ background:transparent }
.dr-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(236px,1fr));gap:12px }
.dr-card{ display:flex;flex-direction:column;gap:6px;padding:0 0 12px;border:1px solid var(--bd-1);
  border-radius:14px;background:var(--bg-1);overflow:hidden;cursor:pointer;min-width:0;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast),transform var(--mk-t-fast) }
.dr-card:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--bd-1));box-shadow:var(--shadow-sm);transform:translateY(-1px) }
.dr-card:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.dr-card > .dr-nm,.dr-card > .dr-chips{ padding-inline:12px }
.dr-card > .dr-nm{ padding-top:10px }
.dr-card > .dr-tr{ margin:8px 12px 0 }
/* ── the preview box: ONE shape, ten contents ───────────────────── */
.dr-pv{ position:relative;display:block;aspect-ratio:16/10;background:var(--bg-2);
  border-bottom:1px solid var(--bd-1);overflow:hidden }
.dr-pv-big{ border:1px solid var(--bd-1);border-radius:12px;aspect-ratio:16/10 }
.dr-frame{ position:absolute;inset:0;display:block;background:#fff;overflow:hidden }
.dr-frame iframe{ position:absolute;left:0;top:0;border:0;transform-origin:0 0;pointer-events:none;
  opacity:0;transition:opacity .3s var(--mk-ease) }
.dr-frame.is-ready iframe{ opacity:1 }
.dr-img{ position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block }
.dr-img-cover{ object-fit:cover }
.dr-badge{ position:absolute;inset-block-end:7px;inset-inline-end:7px;display:inline-flex;align-items:center;gap:4px;
  padding:3px 7px;border-radius:var(--mk-radius-pill);font:700 10px/1.4 var(--mk-font-ui);
  background:color-mix(in srgb,var(--bg-1) 88%,transparent);color:var(--fg-2);
  border:1px solid var(--bd-1);backdrop-filter:blur(6px) }
.dr-badge .mi{ font-size:12px }
.dr-play{ position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:40px;color:#fff;text-shadow:0 1px 10px rgba(0,0,0,.55) }
.dr-wave{ position:absolute;inset:0;display:flex;align-items:center;gap:2px;padding:0 12px }
.dr-wave i{ flex:1;min-width:2px;border-radius:2px;background:color-mix(in srgb,var(--accent) 46%,var(--bg-2)) }
.dr-page{ position:absolute;inset:8px;background:var(--bg-1);border:1px solid var(--bd-1);border-radius:6px;
  padding:10px 11px;display:flex;flex-direction:column;gap:6px;overflow:hidden }
.dr-page-t{ font:800 11.5px/1.25 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
.dr-page-l{ font:500 10px/1.3 var(--mk-font-ui);color:var(--fg-2);padding-bottom:5px;
  border-bottom:1px solid var(--divider);white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.dr-grid-pv{ position:absolute;inset:8px;background:var(--bg-1);border:1px solid var(--bd-1);border-radius:6px;overflow:hidden }
.dr-gr{ display:flex;gap:0;border-bottom:1px solid var(--divider) }
.dr-gr > span{ flex:1;min-width:0;padding:4px 6px;font:500 10px/1.35 var(--mk-font-ui);color:var(--fg-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-inline-end:1px solid var(--divider) }
.dr-gr > span:last-child{ border-inline-end:0 }
.dr-gr-h > span{ font-weight:800;color:var(--fg-1);background:var(--bg-2) }
.dr-slide{ position:absolute;inset:10px;background:var(--bg-1);border:1px solid var(--bd-1);border-radius:6px;
  display:flex;align-items:center;justify-content:center;padding:14px }
.dr-slide-t{ font:800 13px/1.3 var(--mk-font-ui);color:var(--fg-1);text-align:center;text-wrap:pretty }
.dr-slide-n{ position:absolute;inset-block-end:6px;inset-inline-end:8px;font:700 9.5px/1 var(--mk-font-ui);color:var(--fg-3) }
.dr-none{ position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px }
.dr-none .mi{ font-size:30px;color:var(--fg-3) }
.dr-none-t{ font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-2) }
.dr-ext-code{ font:700 10.5px/1.5 var(--mk-font-mono,ui-monospace,monospace);color:var(--fg-2);
  background:var(--bg-2);border-radius:5px;padding:1px 6px }
/* ── the card's two text lines (B63-016: preview first, chips instead of
   three lines of meta/origin text) ────────────────────────────── */
.dr-nm{ display:flex;align-items:center;gap:4px;min-width:0 }
.dr-nm-t{ font:700 13px/1.25 var(--mk-font-ui);color:var(--fg-1);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto }
.dr-nm-in{ flex:1 1 auto;min-width:0;font:700 13px/1.25 var(--mk-font-ui);color:var(--fg-1);
  background:var(--bg-2);border:1px solid var(--accent);border-radius:6px;padding:1px 5px }
.dr-nm-ren{ appearance:none;border:0;background:transparent;cursor:pointer;flex:0 0 auto;
  width:24px;height:24px;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;
  color:var(--fg-3) }
.dr-nm-ren:hover{ background:var(--bg-2);color:var(--fg-1) }
.dr-nm-ren .mi{ font-size:15px }
.dr-chips{ display:flex;align-items:center;gap:5px }
.dr-chip{ display:inline-flex;align-items:center;gap:4px;font:700 10.5px/1 var(--mk-font-ui);
  color:var(--fg-2);background:var(--bg-2);border-radius:var(--mk-radius-pill);padding:4px 9px;
  text-transform:uppercase;letter-spacing:.02em }
.dr-chip .mi{ font-size:12px }
.dr-chip-ext{ font-family:var(--mk-font-mono,ui-monospace,monospace) }
.dr-chip-live{ color:var(--accent-text);background:var(--accent-soft) }
.dr-card.is-live{ border-color:color-mix(in srgb,var(--accent) 26%,var(--bd-1)) }
/* ── the folder card (B63-075) — same tile, an icon instead of a preview ── */
.dr-pv-folder{ display:flex;align-items:center;justify-content:center;background:var(--bg-2) }
.dr-fold-ic{ font-size:40px;color:var(--fg-3) }
.dr-fold:hover .dr-fold-ic{ color:var(--accent-text) }
/* ── the panel: viewer, transport, anchor row, versions ──────────── */
.dr-view{ margin-bottom:12px }
.dr-tr{ display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--bd-1);
  border-radius:11px;background:var(--bg-1);margin-bottom:4px }
.dr-tr-b{ width:34px;height:34px;flex:0 0 auto;border:0;border-radius:50%;cursor:pointer;
  background:var(--accent);color:var(--accent-fg,#fff);display:inline-flex;align-items:center;justify-content:center }
.dr-tr-b .mi{ font-size:20px }
.dr-tr-bar{ flex:1;min-width:0;height:6px;border-radius:3px;background:var(--bg-3);cursor:pointer;position:relative }
.dr-tr-bar i{ position:absolute;left:0;top:0;bottom:0;width:0;border-radius:3px;background:var(--accent) }
.dr-tr-t{ flex:0 0 auto;font:700 11px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.dr-anchor .wl-sumbox-s b{ color:var(--fg-1) }
.dr-ver-n{ flex:0 0 auto;min-width:30px;font:800 12px/1.2 var(--mk-font-ui);color:var(--fg-2);
  font-variant-numeric:tabular-nums }
.dr-goto,.dr-cv-btn{ margin-top:10px }
.dr-cv-btn{ width:100% }
/* ── upload: a real picker over the real classifier ──────────────────── */
.dr-drop{ display:flex;flex-direction:column;align-items:center;gap:6px;padding:20px 16px;cursor:pointer;
  border:1.5px dashed var(--bd-1);border-radius:13px;background:var(--bg-2);text-align:center }
.dr-drop:hover,.dr-drop.is-over{ border-color:var(--accent);background:var(--accent-soft) }
.dr-drop .mi{ font-size:26px;color:var(--accent-text) }
.dr-drop-t{ font:700 13px/1.3 var(--mk-font-ui);color:var(--fg-1) }
.dr-pick .wl-sumbox-t{ word-break:break-all }
/* § M-43 — every control reachable by thumb, in ALL THREE bands this app treats
   as mobile: the pointer type, the narrow WIDTH band (a 390px browser window is
   where the phone reading happens), and MOBILE LANDSCAPE — the short-viewport
   query that already floats the FAB at sections.css:2968. Missing that third one
   left the filter options at 29px and the convert button at 37px on a 924×540
   screen where the app had already switched to its touch affordances; Pablo has
   reported mobile-landscape defects twice before. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  .dr-seg button{ min-height:44px }
  .dr-tr-b{ width:44px;height:44px }
  .dr-tr-bar{ height:10px }
  .dr-card{ min-height:44px }
  /* The panel's primary button is ~37px by default — fine under a mouse, under
     the 44px floor under a thumb, and Drive's convert/open actions are the
     only way to reach the flow they start (§ M-43). */
  .dr-cv-btn,.dr-goto{ min-height:44px }
}
@media (max-width:600px){
  .dr-grid{ grid-template-columns:1fr }
}

/* ═══ B62 § S-18 · SUPPORT ═════════════════════════════════════════
   The tree is CATALOG's (`.ct-*`), the rows are the wallet's (`.wl-sumbox`), the
   filter is the app's `.seg` and the photograph picker is Drive's `.dr-drop`.
   What is new here is only what none of those can do: the state pill, the picked
   subject card, the reason trail, a checkbox row and the order's lifecycle. */
.sp-group{ margin-bottom:14px }
.sp-subj-row,.sp-case,.sp-about,.sp-file,.sp-oline[role="button"]{ cursor:pointer;min-height:48px }
.sp-subj-row:hover,.sp-case:hover,.sp-about:hover,.sp-file:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sp-open-n{ font-weight:800;color:var(--fg-1) }
.sp-row-ic{ font-size:13px;vertical-align:-2px;margin-inline-end:3px;color:var(--fg-2) }
/* the STATE pill — the tint carries the tone, the ink is ordinary text (the
   accent-on-accent-tint defect this batch paid for five times) */
.sp-st{ flex:0 0 auto;display:inline-flex;align-items:center;gap:4px;padding:4px 9px;border-radius:999px;
  font:700 10.5px/1.2 var(--mk-font-ui);color:var(--fg-1);background:var(--bg-2);border:1px solid var(--border);white-space:nowrap }
.sp-st .mi{ font-size:13px }
.sp-st.ok{ background:color-mix(in srgb,var(--mk-ok,#157F4C) 13%,transparent);border-color:color-mix(in srgb,var(--mk-ok,#157F4C) 34%,transparent) }
.sp-st.warn{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 12%,transparent);border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 32%,transparent) }
.sp-st.live{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 34%,transparent) }
.sp-st.done{ background:var(--bg-2);color:var(--fg-2) }
/* the picked subject: the gate, stated */
.sp-subj{ display:flex;align-items:center;gap:11px;padding:12px 13px;margin-bottom:10px;
  border:1px solid var(--border);border-radius:14px;background:var(--bg-1) }
.sp-subj-ic{ flex:0 0 auto;width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-text);font-size:21px }
.sp-subj-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px }
.sp-subj-k{ font:800 9.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3) }
.sp-subj-t{ font:800 14px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.sp-subj-s{ font:500 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
.sp-subj-r{ flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:7px }
.wl-note-row.sp-unlock{ border-style:dashed }
/* the tree's leaves: the only rows that open anything */
.ct-row.sp-leaf{ border-color:color-mix(in srgb,var(--accent) 26%,var(--border)) }
.ct-row.sp-leaf .ct-twist{ color:var(--accent-text);font-size:16px }
.sp-tag-open{ background:var(--accent-soft);color:var(--accent-text);font-weight:800 }
/* the trail a leaf was reached by — B65 W13 (065-167): a visual path on a rail, the reason itself filled */
.sp-trail{ list-style:none;margin:4px 0 10px;padding:0;display:flex;flex-direction:column;position:relative }
.sp-trail-n{ display:flex;align-items:center;gap:11px;min-height:42px;position:relative;color:var(--fg-2);font:600 12.5px/1.3 var(--mk-font-ui) }
.sp-trail-n + .sp-trail-n::before{ content:"";position:absolute;inset-inline-start:13px;top:-14px;height:28px;width:2px;
  background:color-mix(in srgb,var(--accent) 35%,var(--border));border-radius:2px }
.sp-trail-dot{ flex:0 0 auto;width:28px;height:28px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  background:var(--bg-2);border:2px solid color-mix(in srgb,var(--accent) 35%,var(--border));color:var(--fg-2);position:relative;z-index:1 }
.sp-trail-dot .mi{ font-size:15px }
.sp-trail-t{ min-width:0;overflow-wrap:anywhere }
.sp-trail-n.is-leaf{ color:var(--fg-1);font-weight:800;font-size:13.5px }
.sp-trail-n.is-leaf .sp-trail-dot{ background:var(--accent);border-color:var(--accent);color:var(--accent-on,#fff) }
.sp-trail-sep{ display:none }
/* the case's chat row + its call button (B65 W13 · 065-168) */
.sp-chat-row{ cursor:pointer;margin-bottom:12px }
.sp-chat-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sp-chat-row:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.sp-call-btn{ flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center }
/* a checkbox row over the order's own lines */
.sp-ck{ display:flex;align-items:center;gap:10px;cursor:pointer;min-height:48px }
.sp-ck input{ position:absolute;width:1px;height:1px;opacity:0 }
.sp-ck-box{ flex:0 0 auto;font-size:22px;color:var(--fg-3) }
.sp-ck.is-on{ border-color:color-mix(in srgb,var(--accent) 42%,var(--border));background:var(--accent-soft) }
.sp-ck.is-on .sp-ck-box{ color:var(--accent-text) }
.sp-ck input:focus-visible + .sp-ck-box{ outline:2px solid var(--accent);outline-offset:2px;border-radius:4px }
.sp-thumb{ flex:0 0 auto;width:42px;height:42px;object-fit:cover;border-radius:9px;background:var(--bg-2) }
.sp-text{ width:100%;min-height:96px;resize:vertical;font:500 12.5px/1.5 var(--mk-font-ui) }
.sp-acts{ display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:14px }
.sp-acts .wl-close-btn,.sp-acts .wl-chip{ min-height:38px }
/* B63-079 — Chat/Call on the case panel, chat's unread count as a bubble. */
.sp-case-acts{ display:flex;gap:8px;margin-bottom:12px }
.sp-case-acts .wl-chip{ position:relative }
.sp-case-badge{ display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;
  padding:0 4px;margin-inline-start:4px;border-radius:999px;background:var(--mk-danger,#e05252);color:#fff;
  font:800 10px var(--mk-font-ui);line-height:1 }
.sp-code{ flex:0 0 auto;font:800 11px/1.2 var(--mk-font-mono,ui-monospace,monospace);color:var(--fg-2);
  padding:5px 7px;border-radius:7px;background:var(--bg-2);letter-spacing:.02em }
/* what the member said, and what has happened since */
.sp-quote{ padding:11px 12px;border-radius:12px;background:var(--bg-2);border:1px solid var(--border);
  font:500 12.5px/1.55 var(--mk-font-ui);color:var(--fg-1);text-wrap:pretty }
.sp-upd{ display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:12px;background:var(--bg-1);
  border:1px solid var(--border);margin-bottom:7px }
.sp-upd.is-mine{ background:var(--bg-2) }
.sp-upd-h{ display:flex;align-items:baseline;justify-content:space-between;gap:8px;
  font:700 12px/1.3 var(--mk-font-ui);color:var(--fg-1) }
.sp-upd-t{ font:500 12px/1.5 var(--mk-font-ui);color:var(--fg-2);text-wrap:pretty }
/* the order: its lifecycle, and its lines */
.sp-life{ display:flex;flex-wrap:wrap;align-items:stretch;gap:5px;margin-bottom:8px }
.sp-life-st{ display:flex;flex-direction:column;gap:2px;padding:7px 10px;border-radius:11px;
  border:1px solid var(--border);background:var(--bg-1);font:700 11px/1.2 var(--mk-font-ui);color:var(--fg-2) }
.sp-life-st .mi{ font-size:15px }
.sp-life-st.is-done{ color:var(--fg-2) }
.sp-life-st.is-now{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 40%,transparent);color:var(--fg-1);font-weight:800 }
.sp-life-st.is-next{ border-style:dashed;color:var(--fg-3) }
.sp-life-st.warn{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 12%,transparent);color:var(--fg-1) }
.sp-life-sep{ align-self:center;font-size:16px;color:var(--fg-3) }
.sp-qty{ flex:0 0 auto;min-width:38px;font:800 13px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.sp-line-amt{ flex:0 0 auto;font:800 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
/* § M-43 — the same three bands Drive was corrected for: pointer type, the
   narrow width band, and mobile LANDSCAPE. Every control in this section is the
   only way to reach the flow it starts. */
.sp-seg .wl-fee-note{ font-weight:700 }
/* The count inside a segment takes the segment's own ink — on the ACTIVE pill
   the label is `--accent-text` and a count left at `--fg-2` reads as a second,
   quieter voice on a surface that has already changed colour. Applies to every
   `.seg` with counts in it (Drive's family switch is the same shape). */
.seg button .wl-fee-note{ color:inherit }
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  .sp-seg button{ min-height:44px }
  /* `button.wl-chip` carries the app's 40px floor at specificity (0,1,1), which
     BEATS a bare `.sp-change` — the 40px measured on a phone was the old floor
     winning, not the new one missing. */
  .sp-acts .wl-close-btn,.sp-acts .wl-chip,button.wl-chip.sp-change{ min-height:44px }
  .sp-subj-row,.sp-case,.sp-about,.sp-file,.sp-ck{ min-height:48px }
  .sp-life-st{ min-height:44px;justify-content:center }
}
@media (max-width:600px){
  .sp-subj{ align-items:flex-start }
  .sp-subj-r{ align-items:flex-end }
}

/* ═══ B62 § S-16 · WORKSHOP ▸ CANVAS ═══════════════════════════════
   Pablo: "Canvas (similar to figma, paint and powerpoint in the sense that I can
   drag and drop, create elements, move, format and assign different variables.
   Just a simple canvas where people can work on them) … All of these items would
   be live edited."
   The list card is DRIVE's card with the board itself as its thumbnail; the
   inspector's rows, notes and actions are the wallet's; the tab strip is the
   app's `.seg`. What is genuinely new is only the working surface: a sheet, an
   element, eight handles, a swatch, and a bottom sheet for the inspector on a
   phone (because a fixed side column at 390px leaves no canvas at all).
   B63-115 (Pablo: "The weekly calendar is broken now, there's a huge whitespace
   at the left of the time bar") — this list used `.wk-grid`/`.wk-card`, the
   SAME class names as the Schedule ▸ Week calendar's own grid below, with a
   completely different `grid-template-columns`. Being later in this file, it
   silently won the cascade and stretched the calendar's 56px time-axis column
   into a 252px+ card column. Renamed to `wkc-*` (Workshop Canvas) so the two
   never collide again. */
.wkc-grid{ display:grid;grid-template-columns:repeat(auto-fill,minmax(252px,1fr));gap:14px }
.wkc-card{ display:flex;flex-direction:column;gap:6px;padding:0 0 12px;border:1px solid var(--bd-1);
  border-radius:14px;background:var(--bg-1);overflow:hidden;cursor:pointer;min-width:0;
  transition:border-color var(--mk-t-fast),box-shadow var(--mk-t-fast),transform var(--mk-t-fast) }
.wkc-card:hover{ border-color:color-mix(in srgb,var(--accent) 32%,var(--bd-1));box-shadow:var(--shadow-sm);transform:translateY(-1px) }
.wkc-card:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.wkc-card > .wkc-card-nm,.wkc-card > .wkc-card-meta,.wkc-card > .wkc-mark{ padding-inline:12px }
.wkc-card > .wkc-card-nm{ padding-top:10px }
.wkc-thumb{ position:relative;display:block;aspect-ratio:16/10;overflow:hidden;background:var(--bg-2);
  border-bottom:1px solid var(--bd-1) }
.wkc-thumb-in{ position:absolute;left:0;top:0;display:block;transform-origin:0 0;direction:ltr;
  border:0;box-shadow:none }
.wkc-card-nm{ font:700 13.5px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap }
.wkc-card-meta{ font:500 11px/1.3 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums }
.wkc-mark{ display:inline-flex;align-items:center;gap:5px;align-self:flex-start;
  font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-2);background:var(--bg-2);
  border-radius:var(--mk-radius-pill);padding:4px 9px }
.wkc-mark .mi{ font-size:13px }
.wkc-mark.is-live{ color:var(--fg-1);background:var(--accent-soft) }
.wkc-mark.is-live .mi{ color:var(--accent-text) }
/* ── the open board: the page stops scrolling and the STAGE becomes the
      scroller. The page header is replaced by the bar, which carries the board's
      name and the way back — two headers on a 390px screen leave no canvas. ── */
.page-view.wk-open .page-h{ display:none }
.page-view.wk-open > .page{ display:flex;flex-direction:column;min-height:0;overflow:hidden;padding-block-end:12px }
.page-view.wk-open [data-wk-pane]{ flex:1;min-height:0;display:flex;flex-direction:column }
/* ── B63-099/100/101 — the open FLOWCHART, same recipe as the open canvas
   above: the page stops scrolling, the bar replaces the header, and
   `MoccaWorkflow.render`'s own host (`.wf-host`) stretches to fill what's
   left — the exact sizing problem 099 named ("not taking as much space as
   it could") when this used to be a fixed-size modal. ── */
.page-view.fc-open .page-h{ display:none }
.page-view.fc-open > .page{ display:flex;flex-direction:column;min-height:0;overflow:hidden;padding-block-end:12px }
.page-view.fc-open [data-fc-pane]{ flex:1;min-height:0;display:flex;flex-direction:column }
.fc-body{ flex:1;min-height:0;display:flex;gap:12px }
.wf-host-fc{ flex:1 1 auto;min-width:0;min-height:0;display:flex }
.wf-host-fc .wf{ flex:1;min-width:0 }
.wf-host-fc .wf-scroll{ min-height:280px }
.fc-info{ flex:0 0 auto;width:312px;max-width:42vw;box-sizing:border-box;
  overflow:auto;padding:12px;border:1px solid var(--bd-1);border-radius:var(--mk-radius-lg) }
@media (max-width:900px){
  .fc-body{ flex-direction:column }
  .fc-info{ width:auto;max-width:none;max-height:46% }
}
.wk-bar{ display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:9px }
.wk-bar-sp{ flex:1;min-width:0 }
.wk-bar-nm{ display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:10px;cursor:pointer;
  font:800 14.5px/1.2 var(--mk-font-ui);color:var(--fg-1);max-width:min(46vw,420px);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.wk-bar-nm:hover{ background:var(--bg-2) }
.wk-bar-nm:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.wk-bar-nm .mi{ font-size:15px;color:var(--fg-3);flex:0 0 auto }
/* B63-097 — icon-only chips read as a stretched rectangle at the base
   `.wl-chip` padding (5px vertical, 9px horizontal for icon variants); a
   fixed square box + centred content is the actual 1:1 he asked for. */
button.wl-chip.wk-ic-btn{ width:30px;height:30px;padding:0;justify-content:center }
button.wl-chip.is-on{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 40%,var(--bd-1));color:var(--fg-1) }
button.wl-chip.is-danger{ color:var(--mk-danger,#C81E1E);border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 34%,var(--bd-1)) }
button.wl-chip[disabled]{ opacity:.4;cursor:default }
.wk-zoom{ display:inline-flex;align-items:center;gap:4px }
button.wl-chip.wk-zoom-v{ min-width:58px;justify-content:center;font-variant-numeric:tabular-nums }
/* ── the three columns ── */
.wk-body{ flex:1;min-height:0;display:grid;gap:10px;grid-template-columns:142px minmax(0,1fr) 318px }
.wk-pal{ display:flex;flex-direction:column;gap:6px;padding:9px;min-height:0;overflow:auto;
  border:1px solid var(--bd-1);border-radius:14px;background:var(--bg-1) }
.wk-pal-h{ font:800 9.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3);padding:2px 2px 3px }
button.wk-tool{ display:flex;align-items:center;gap:8px;min-height:40px;padding:8px 9px;cursor:grab;
  border:1px solid var(--bd-1);border-radius:11px;background:var(--bg-1);text-align:start;
  font:700 12px/1.2 var(--mk-font-ui);color:var(--fg-1) }
button.wk-tool:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--bd-1));background:var(--accent-soft) }
button.wk-tool:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
button.wk-tool .mi{ font-size:18px;color:var(--fg-2);flex:0 0 auto }
button.wk-tool:hover .mi{ color:var(--accent-text) }
.wk-tool-l{ min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.wk-pal-tip{ font:500 10.5px/1.45 var(--mk-font-ui);color:var(--fg-2);padding:3px 2px;text-wrap:pretty }
.wk-stage{ position:relative;min-height:0;overflow:auto;padding:16px;display:flex;
  justify-content:center;align-items:flex-start;-webkit-overflow-scrolling:touch;
  background:var(--bg-2);border:1px solid var(--bd-1);border-radius:14px }
.wk-stage.is-over{ border-color:var(--accent);box-shadow:inset 0 0 0 2px var(--accent-soft) }
.wk-wrap{ position:relative;flex:0 0 auto }
.wk-sheet{ position:absolute;left:0;top:0;transform-origin:0 0;direction:ltr;
  border:1px solid var(--bd-1);box-shadow:var(--shadow-sm) }
/* The grid is an OVERLAY, not a background-image: the sheet's own colour is set
   inline (it is a property of the board), and an inline `background` shorthand
   wipes any background-image a stylesheet tries to add. */
.wk-sheet.is-grid::before{ content:'';position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:linear-gradient(to right,var(--divider) 1px,transparent 1px),
    linear-gradient(to bottom,var(--divider) 1px,transparent 1px);
  background-size:64px 64px }
/* ── one element ── */
.wk-el{ position:absolute;box-sizing:border-box;cursor:grab;touch-action:none;display:block }
.wk-el:focus-visible{ outline:2px solid var(--accent);outline-offset:3px }
.wk-el.is-sel{ box-shadow:0 0 0 2px var(--accent) }
.wk-el-t{ position:absolute;inset:0;display:flex;padding:8px 10px;overflow:hidden;
  white-space:pre-wrap;word-break:break-word;text-wrap:pretty }
.wk-el-empty{ color:var(--fg-4);font-style:italic;font-weight:600 }
.wk-el-img{ position:absolute;inset:0;width:100%;height:100%;display:block;border-radius:inherit }
.wk-el-ph{ position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  font:600 11px/1.3 var(--mk-font-ui);color:var(--fg-2);text-align:center;padding:8px }
.wk-el-ph .mi{ font-size:24px;color:var(--fg-3) }
.wk-k-line{ display:flex;align-items:center }
.wk-k-line > i{ display:block;width:100%;border-radius:999px }
.wk-el-live{ position:absolute;top:-9px;inset-inline-end:-9px;width:20px;height:20px;border-radius:50%;
  background:var(--accent);color:var(--accent-fg,#fff);display:grid;place-items:center;
  box-shadow:0 1px 4px rgba(0,0,0,.18) }
.wk-el-live .mi{ font-size:13px }
/* WHY A HANDLE IS SIZED IN INVERSE-ZOOM UNITS
   The sheet is `transform:scale(z)`, so a handle written as 12px measured FOUR
   PHYSICAL PIXELS on a phone (z≈0.27) — the phone probe caught it, and nobody
   can grab that with a thumb. A hit target must be specified in the size the
   THUMB meets, so the sheet publishes `--wk-iz` (1/z, written inline by
   sheetStyle) and every handle dimension, offset and border is multiplied by
   it: 14 physical px at any zoom, 22 in the mobile bands. */
.wk-h{ position:absolute;box-sizing:border-box;width:var(--wk-hs,14px);height:var(--wk-hs,14px);background:var(--bg-1);
  border:var(--wk-hb,2px) solid var(--accent);border-radius:calc(var(--wk-hs,14px) / 4);touch-action:none }
.wk-h-nw{ left:calc(var(--wk-hs,14px) / -2);top:calc(var(--wk-hs,14px) / -2);cursor:nwse-resize }
.wk-h-ne{ right:calc(var(--wk-hs,14px) / -2);top:calc(var(--wk-hs,14px) / -2);cursor:nesw-resize }
.wk-h-se{ right:calc(var(--wk-hs,14px) / -2);bottom:calc(var(--wk-hs,14px) / -2);cursor:nwse-resize }
.wk-h-sw{ left:calc(var(--wk-hs,14px) / -2);bottom:calc(var(--wk-hs,14px) / -2);cursor:nesw-resize }
.wk-h-n{ left:50%;top:calc(var(--wk-hs,14px) / -2);margin-inline-start:calc(var(--wk-hs,14px) / -2);cursor:ns-resize }
.wk-h-s{ left:50%;bottom:calc(var(--wk-hs,14px) / -2);margin-inline-start:calc(var(--wk-hs,14px) / -2);cursor:ns-resize }
.wk-h-w{ left:calc(var(--wk-hs,14px) / -2);top:50%;margin-block-start:calc(var(--wk-hs,14px) / -2);cursor:ew-resize }
.wk-h-e{ right:calc(var(--wk-hs,14px) / -2);top:50%;margin-block-start:calc(var(--wk-hs,14px) / -2);cursor:ew-resize }
/* ── the inspector ── */
.wk-side{ display:flex;flex-direction:column;min-height:0;overflow:hidden;
  border:1px solid var(--bd-1);border-radius:14px;background:var(--bg-1) }
.wk-side-h{ display:flex;align-items:center;gap:8px;padding:8px;border-bottom:1px solid var(--divider) }
.wk-seg{ flex:1;min-width:0 }
/* The app's `.seg button` is 27px — fine for a filter strip, not for the only
   control that switches between three panes or binds an element to a variable.
   Raised HERE at equal specificity (0,1,1) and later in the file, so it wins
   without touching every other `.seg` in the app; raised again to 44px in the
   three mobile bands below (a rule that does not out-specify the floor it
   raises loses silently — the trap session 13 paid for). */
.wk-seg button,.wk-seg2 button,.wk-seg3 button{ min-height:34px }
.wk-seg button{ font-size:11.5px }
.wk-side-b{ flex:1;min-height:0;overflow:auto;padding:10px 12px 22px }
.wk-side-b .wl-sech:first-child{ margin-top:2px }
.wk-selhead{ display:flex;align-items:center;gap:10px;padding:9px 10px;margin-bottom:8px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-1) }
/* an ICON on a tint is a glyph at 19px, not body text — 3:1 is its bar */
.wk-selic{ flex:0 0 auto;width:34px;height:34px;border-radius:10px;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-text);font-size:19px }
.wk-selm{ flex:1;min-width:0;display:flex;flex-direction:column;gap:1px }
.wk-selk{ font:800 9.5px/1 var(--mk-font-ui);letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3) }
.wk-selnm{ font:800 13px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.wk-frow,.wk-nrow{ display:flex;align-items:center;gap:9px;margin:7px 0 }
.wk-frow{ align-items:flex-start;flex-wrap:wrap }
.wk-frow > label,.wk-nrow > label{ flex:0 0 96px;font:600 11.5px/1.35 var(--mk-font-ui);color:var(--fg-2) }
.wk-nums{ display:grid;grid-template-columns:1fr 1fr;gap:0 10px }
.wk-nums .wk-nrow > label{ flex:0 0 42px }
input.ent-input.wk-num{ flex:1;min-width:0;font-variant-numeric:tabular-nums }
.wk-text{ width:100%;min-height:74px;resize:vertical;font:500 12.5px/1.5 var(--mk-font-ui) }
.wk-sw{ display:flex;flex-wrap:wrap;gap:6px;flex:1;min-width:0 }
/* 32px, not 28: a swatch IS a control — the only road to an element's colour —
   so it meets the same floor as every other control in the panel. It wraps to
   two rows in a 318px inspector, which is what `.wk-sw`'s flex-wrap is for.
   38px in the mobile band below. */
button.wk-swb{ width:32px;height:32px;padding:0;border:1px solid var(--bd-1);border-radius:8px;cursor:pointer;
  background:var(--bg-1);display:grid;place-items:center }
button.wk-swb > i{ display:block;width:100%;height:100%;border-radius:7px }
button.wk-swb.is-on{ border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft) }
button.wk-swb:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
button.wk-swb.is-none > i{ background:
  linear-gradient(135deg,transparent 45%,var(--mk-danger,#C81E1E) 45%,var(--mk-danger,#C81E1E) 55%,transparent 55%),var(--bg-2) }
/* what the value says right now — the tint carries the state, the ink is
   ordinary text (the accent-on-accent-tint defect this batch paid for) */
.wk-val{ display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:8px 0;
  padding:9px 11px;border:1px solid var(--border);border-radius:12px;background:var(--bg-2) }
.wk-val.is-live{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 34%,transparent) }
/* accent ink on its OWN tint is 3.9:1 — the tint says "live", --fg-1 is the ink */
.wk-val.is-live .wk-val-v,.wk-val.is-live .wk-val-k{ color:var(--fg-1) }
.wk-val-k{ font:700 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
.wk-val-v{ font:800 14px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;
  text-align:end;min-width:0;word-break:break-word }
.wl-sumbox.wk-from,.wl-sumbox.wk-src{ cursor:pointer;min-height:48px }
.wl-sumbox.wk-from:hover,.wl-sumbox.wk-src:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.wk-from-go{ flex:0 0 auto;font-size:18px;color:var(--fg-3) }
.wk-ck{ display:flex;align-items:center;gap:9px;cursor:pointer;min-height:44px;padding:6px 9px;margin-top:6px;
  border:1px solid var(--border);border-radius:11px;font:600 12px/1.35 var(--mk-font-ui);color:var(--fg-1) }
.wk-ck input{ position:absolute;width:1px;height:1px;opacity:0 }
.wk-ck-b{ flex:0 0 auto;font-size:21px;color:var(--fg-3) }
.wk-ck.is-on{ border-color:color-mix(in srgb,var(--accent) 42%,var(--border));background:var(--accent-soft) }
/* a 21px checkbox glyph on a tint — a glyph's bar is 3:1 */
.wk-ck.is-on .wk-ck-b{ color:var(--accent-text) }
.wk-ck input:focus-visible + .wk-ck-b{ outline:2px solid var(--accent);outline-offset:2px;border-radius:4px }
.wk-acts{ display:flex;flex-wrap:wrap;gap:7px;margin:9px 0 4px }
/* ── the variables pane ── */
.wk-var{ display:flex;flex-direction:column;gap:6px;padding:10px 11px;margin-bottom:9px;
  border:1px solid var(--border);border-radius:13px;background:var(--bg-1) }
.wk-var.is-live{ border-color:color-mix(in srgb,var(--accent) 30%,var(--border)) }
.wk-var-h{ display:flex;align-items:baseline;justify-content:space-between;gap:9px }
.wk-var-nm{ font:800 12.5px/1.25 var(--mk-font-ui);color:var(--fg-1);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap }
.wk-var-v{ flex:0 0 auto;font:800 12.5px/1.2 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.wk-var.is-live .wk-var-v{ color:var(--fg-1) }
.wk-var-from{ display:flex;align-items:center;gap:5px;font:600 11px/1.35 var(--mk-font-ui);color:var(--fg-2) }
.wk-var-from .mi{ font-size:14px;color:var(--fg-3) }
.wk-var-f{ display:flex;align-items:center;gap:6px }
.wk-var-used{ flex:1;min-width:0;font:600 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2) }
button.wl-chip.wk-add-var{ width:100%;justify-content:center;margin-bottom:6px }
/* ── the layers pane ── */
.wk-lay{ display:flex;align-items:center;gap:8px;padding:7px 9px;margin-bottom:6px;cursor:pointer;
  border:1px solid var(--border);border-radius:11px;background:var(--bg-1);min-height:48px }
.wk-lay:hover{ border-color:color-mix(in srgb,var(--accent) 40%,var(--border)) }
.wk-lay:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }
.wk-lay.is-on{ background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 42%,var(--border)) }
.wk-lay.wl-dragging{ opacity:.5 }
.wk-lay-grip{ flex:0 0 auto;font-size:18px;color:var(--fg-3);cursor:grab }
.wk-lay-ic{ flex:0 0 auto;font-size:18px;color:var(--fg-2) }
.wk-lay-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:1px }
.wk-lay-t{ font:700 12px/1.25 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap }
.wk-lay-s{ font:500 10.5px/1.3 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums }
/* a 15px glyph, not body text */
.wk-lay-live{ flex:0 0 auto;font-size:15px;color:var(--accent-text) }
/* ── RESPONSIVE. Under 1000px the inspector cannot be a column — at 390px it
      would leave no canvas — so it becomes a bottom sheet with a close button
      (never a dead end, § M-43), and the palette becomes a scrolling strip. The
      FAB is hidden while that sheet is up: the floors rule (§ M-88) says the
      floating button lives only over main content. ── */
@media (max-width:1000px){
  .wk-body{ grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) }
  .wk-pal{ flex-direction:row;align-items:center;overflow-x:auto;overflow-y:hidden;padding:7px 8px }
  .wk-pal-h{ display:none }
  button.wk-tool{ flex:0 0 auto }
  .wk-pal-tip{ flex:0 0 auto;max-width:230px;padding-inline-start:6px }
  .wk-side{ position:fixed;inset-inline:0;inset-block-end:0;max-height:66dvh;z-index:640;display:none;
    border-radius:16px 16px 0 0;border-bottom:0;box-shadow:0 -14px 34px rgba(0,0,0,.2) }
  .wk-body.side-open .wk-side{ display:flex }
  .wk-bar-nm{ max-width:min(52vw,320px) }
}
@media (min-width:1001px){
  button.wl-chip.wk-side-btn,button.wl-chip.wk-side-x{ display:none }
}
/* § M-43 — the same three bands the rest of this batch was corrected for:
   pointer type, the narrow WIDTH band, and mobile LANDSCAPE. Every control here
   is the only way to reach what it does, and `button.wl-chip` holds the app's
   40px floor at specificity (0,1,1) — so a raise has to OUT-SPECIFY it. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  button.wl-chip.wk-ic-btn,button.wl-chip.wk-back,button.wl-chip.wk-zoom-v,
  button.wl-chip.wk-side-btn,button.wl-chip.wk-add-var,button.wl-chip.is-danger{ min-height:44px }
  button.wk-tool{ min-height:44px }
  /* The stacking chips (To front / Forward / Backward / To back) are plain
     `.wl-chip`s, so the base 40px floor was all they had — the landscape probe
     measured four of them at 40. A raise has to OUT-SPECIFY the floor it
     raises, hence the two-class selectors. */
  .wk-acts button.wl-chip,.wk-side-b button.wl-chip,.wk-bar button.wl-chip{ min-height:44px }
  .wk-bar button.wl-chip.wk-ic-btn{ width:44px;height:44px }
  .wk-bar-nm{ min-height:44px }
  input.ent-input.wk-num{ min-height:44px }
  .wk-side-b select.ent-input,.wk-side-b input.ent-input{ min-height:44px }
  .wk-side-b .seg button,.wk-seg button,.wk-seg2 button,.wk-seg3 button{ min-height:44px }
  button.wk-swb{ width:38px;height:38px }
  /* FALLBACK ONLY. The real size is computed per element and written inline by
     elHtml(), because a 22px thumb target is 92 BOARD px at a phone's fit-zoom
     and has to be capped against the element it resizes. This rule is what a
     paint that did not carry the band falls back to. */
  .wk-sheet{ --wk-hs:calc(22px * var(--wk-iz,1));--wk-hb:calc(2px * var(--wk-iz,1)) }
  .wkc-card{ min-height:44px }
  .wk-lay{ min-height:48px }
}
@media (max-width:600px){
  .wkc-grid{ grid-template-columns:1fr }
  .wk-stage{ padding:10px }
  .wk-nums{ grid-template-columns:1fr }
  .wk-frow > label,.wk-nrow > label{ flex:0 0 84px }
}

/* ═══ B62 § S-55 · ROLES AS A TREE ═════════════════════════════════
   "a list of expandable boxes with nested children (similar to entities or
   routes) where I would see the divisions (role groups), segments (role) and
   assignments (users assigned to that segment)"
   The tree IS Catalog's (`.ct-row`, depth as `--ct-d`), reused a third time —
   Support's reason tree was the second. What is new is only what a role tree has
   that a product tree does not: a level's own verbs on its row, and an
   assignment leaf that is a person rather than a record. */
.rg-tree{ gap:6px }
.rg-node{ gap:6px }
.ct-row.rg-row{ gap:10px }
/* A LEAF IS A PERSON, so it is not a twist target and says so by its cursor. */
.ct-row.rg-leaf{ cursor:default;background:var(--bg-2);border-style:dashed }
.ct-row.rg-leaf:hover{ border-color:var(--border) }
/* B63 W7 (123) — a real user row opens the shared person panel. */
.ct-row.rg-leaf.rg-openable{ cursor:pointer;border-style:solid }
.ct-row.rg-leaf.rg-openable:hover{ border-color:var(--accent);background:var(--bg-3) }
.rg-client{ display:inline-flex;align-items:center;height:18px;padding:0 7px;margin-inline-start:8px;border-radius:999px;border:1px solid var(--border);font:600 10px/1 var(--mk-font-ui);letter-spacing:.04em;color:var(--fg-2);vertical-align:2px; }
.rg-mark{ flex:0 0 auto;width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-text) }
.rg-mark .mi{ font-size:18px }
.ct-row.rg-row .av{ flex:0 0 auto }
/* The row's own verbs. They must not read as a twist, so they are chips — and
   the twist handler ignores clicks that land on one. */
/* B63-126 — "the add/delete buttons within the box are not 1:1 aspect ratio":
   a chip with inline padding is as wide as its padding says; a row verb is an
   icon, so it is a square. */
.ct-row.rg-row .rg-act{ flex:0 0 auto;width:32px;height:32px;min-height:0;aspect-ratio:1;padding:0;justify-content:center }
.wl-note-row.rg-empty{ margin-inline-start:calc(var(--ct-d,0) * 18px);margin-block:2px }
/* B63 W7 (124) — the Assign picker: an inline multi-select + Add button
   right under the row, replacing the old panel + checkbox-list. */
.rg-assign-inline{ margin:6px 0 6px calc(var(--ct-d,0) * 18px + 32px);display:flex;flex-direction:column;gap:6px }
.rg-assign-row{ display:flex;align-items:center;gap:8px }
.rg-assign-row .cs{ flex:1;min-width:0 }
/* § M-43 — the three bands. A tree row is the only way to reach the level under
   it, and its verbs are the only way to add or remove one. */
@media (pointer:coarse),(max-width:600px),(max-height:599px) and (orientation:landscape){
  .ct-row.rg-row{ min-height:56px }
  .ct-row.rg-row .rg-act{ width:44px;height:44px;min-height:44px }
  .wl-note-row.rg-empty{ margin-inline-start:calc(var(--ct-d,0) * 12px) }
}
@media (max-width:600px){
  /* At 390px a 3-level indent eats the row; the depth step halves and the row
     wraps its verbs under its label rather than squeezing the name to nothing. */
  .ct-row.rg-row{ flex-wrap:wrap;margin-inline-start:calc(var(--ct-d,0) * 10px) }
  .ct-row.rg-row .ct-row-m{ flex:1 1 60% }
}

/* An assignment the app cannot resolve to a person: a real state, marked so it
   can be found and removed rather than reading as a name nobody recognises. */
.ct-row.rg-ghost{ border-color:color-mix(in srgb,var(--mk-danger,#C81E1E) 30%,var(--border)) }
.ct-row.rg-ghost .ct-row-t{ color:var(--fg-2);font-style:italic }
.ct-row.rg-ghost .rg-mark{ background:color-mix(in srgb,var(--mk-danger,#C81E1E) 13%,transparent);color:var(--mk-danger,#C81E1E) }

/* ═══ B64-Q3 — Frontend: the tree beside the page it describes ═══════════
   Desktop: tree (flexible) + a sticky live preview column. Every row below a
   domain or route leaf is an ASSET (its own chip colour per scope); hovering a
   row rings its instances on the preview, pointing at the preview drills the
   tree. Below 1100px the preview column steps aside (B64 W5 brings it back
   preview-first on phones, with the tree as a collapsed bar). */
.fe-split{ display:grid;grid-template-columns:minmax(0,1fr) minmax(420px,54%);gap:18px;align-items:start; }
.fe-split.fe-wide{ grid-template-columns:minmax(280px,30%) minmax(0,1fr); }
.fe-tree-col{ min-width:0; }
/* Audit A — the inspector column: what is selected, the device stage (address,
   screen sizes + touch, the device), and the Details docked under it. It holds
   the viewport's height so the stage has a real box to fit the device into. */
.fe-pv-col{ position:sticky;top:96px;display:flex;flex-direction:column;gap:8px;min-width:0;
  height:calc(100dvh - 176px);min-height:420px;
  padding:10px;border:1px solid var(--border);border-radius:16px;background:var(--bg-1); }
.fe-pv-bar{ display:flex;flex-direction:column;gap:6px;min-width:0;flex:0 0 auto; }
.fe-pv-t{ display:flex;align-items:center;gap:7px;min-width:0;min-height:30px;font:600 12.5px var(--mk-font-ui);color:var(--fg-2); }
.fe-pv-sel{ display:flex;align-items:center;gap:7px;min-width:0;flex:1 1 auto; }
.fe-pv-sel > .mi{ font-size:17px;color:var(--accent-text); }
.fe-pv-sel b{ font:700 13.5px var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0; }
.fe-pv-sel .nt-lv{ flex:0 0 auto; }
.fe-pv-crumb{ display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-height:22px; }
.fe-pv-crumb:empty{ display:none; }
.fe-pv-sample{ flex:0 0 auto; }
.fe-pv-sample[hidden]{ display:none; }
.fe-pv-col .pvs-tool:disabled{ opacity:.4;cursor:not-allowed; }
.fe-cr{ display:inline-flex;align-items:center;height:20px;padding:0 7px;border-radius:6px;font:600 11px var(--mk-font-ui);
  background:var(--bg-input);color:var(--fg-1);border:1px solid var(--border); }
.fe-cr-sep{ color:var(--fg-3);font-size:12px; }
.fe-cr-shell{ border-color:color-mix(in srgb,#22526A 45%,var(--border)); }
.fe-cr-template{ border-color:color-mix(in srgb,#6D5BD0 50%,var(--border)); }
.fe-cr-form{ border-color:color-mix(in srgb,#C77B12 50%,var(--border)); }
.fe-cr-component{ border-color:color-mix(in srgb,var(--accent) 50%,var(--border)); }
.fe-cr-icon{ border-color:color-mix(in srgb,#9A5B8F 50%,var(--border)); }
.fe-pv-stage{ position:relative;flex:1 1 auto;min-height:0;display:flex;flex-direction:column; }
/* the device sits at the top of its canvas: before the column has scrolled to
   its sticky spot its bottom can be below the fold, the device never is */
.fe-pv-stage .pvs-stage{ justify-content:flex-start; }
/* Details, docked: the stage keeps the top ~45%, the editor takes the rest */
.fe-details{ display:none;min-height:0; }
.fe-pv-col.fe-has-details .fe-pv-stage{ flex:0 0 44%; }
.fe-pv-col.fe-has-details .fe-details{ display:flex;flex:1 1 auto;min-height:0; }
.fe-details > .route-edit-panel.rt-docked{ position:relative;flex:1 1 auto;min-height:0;width:100%;overflow:hidden;
  border:1px solid var(--border);border-radius:14px;background:var(--bg-1);display:none;flex-direction:column; }
.fe-details > .route-edit-panel.rt-docked.open{ display:flex; }
.route-edit-panel.rt-docked > .panel-hd{ padding:10px 14px; }
.route-edit-panel.rt-docked > .panel-body{ flex:1 1 auto;min-height:0;overflow-y:auto; }
.route-edit-panel.rt-docked [data-route-hd-preview]{ display:none !important; }
.route-edit-panel.rt-docked .ent-slide{ border-radius:14px; }
.fe-pv-wide{ flex:0 0 auto; }
@media (max-width:1099px){
  .fe-split{ grid-template-columns:minmax(0,1fr); }
  .fe-pv-col{ display:none; }
  .fe-pv-t .fe-pv-wide{ display:none; }
}

/* asset rows inside the route tree */
.nt-as-node{ position:relative; }
.nt-as-block{ display:flex;flex-direction:column;gap:6px; }
.nt-as-box{ padding:7px 10px;border-style:dashed;background:color-mix(in srgb,var(--bg-2) 60%,var(--bg-1)); }
.nt-as-box .nt-ic{ width:24px;height:24px;font-size:15px;border-radius:7px; }
.nt-as-box .nt-label{ font-weight:600; }
.nt-as-box.is-hot{ border-color:var(--accent);border-style:solid;background:var(--accent-soft); }
/* Audit A — the row the preview is showing reads as selected (any level) */
.fe-tree-col .nt-box.is-sel{ border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent);background:var(--accent-soft); }
.nt-as-box.is-sel{ border-style:solid;border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent);background:var(--accent-soft); }
.nt-lv-as{ color:#fff; }
.nt-lv-as-shell{ background:#22526A; }
.nt-lv-as-template{ background:#6D5BD0; }
.nt-lv-as-form{ background:#C77B12; }
.nt-lv-as-component{ background:#0E7C86; }
.nt-lv-as-icon{ background:#9A5B8F; }
.nt-as-shell > .nt-box .nt-ic{ background:#22526A;color:#fff; }
.nt-as-template > .nt-box .nt-ic{ background:color-mix(in srgb,#6D5BD0 18%,transparent);color:#6D5BD0; }
.nt-as-form > .nt-box .nt-ic{ background:color-mix(in srgb,#C77B12 18%,transparent);color:#C77B12; }
.nt-as-icon > .nt-box .nt-ic{ background:var(--bg-input);color:var(--fg-1); }
html[data-theme="dark"] .nt-as-template > .nt-box .nt-ic{ color:#b3a6ff; }
html[data-theme="dark"] .nt-as-form > .nt-box .nt-ic{ color:#f0b35e; }
.nt-as-n{ padding:1px 7px;border-radius:999px;background:var(--bg-input);border:1px solid var(--border);font:700 10.5px var(--mk-font-ui);color:var(--fg-2); }
.nt-as-note{ font:500 11px var(--mk-font-ui);color:var(--fg-3);font-style:italic;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0; }
.nt-as-acts{ margin-inline-start:auto; }
.nt-as-declared, .nt-as-none{ display:flex;align-items:center;gap:6px;padding:4px 2px;font:500 11.5px var(--mk-font-ui);color:var(--fg-3); }
.nt-as-declared .mi, .nt-as-none .mi{ font-size:15px; }
.nt-as-none{ color:var(--mk-danger); }

/* ═══ B65 W14 — type chips, 1:1 hover, unstyled flags (065-039 · 056 · 058 · 060) ═══
   The kind reads AFTER the name as a quiet sentence-case chip (App · Domain ·
   Sub-domain · Route · Shell · Template · Form · Component · Icon), tinted by
   kind — never an ALL-CAPS sticker ahead of the name. */
.nt-type{ flex:0 0 auto;display:inline-flex;align-items:center;height:19px;padding:0 7px;border-radius:999px;
  font:600 10.5px var(--mk-font-ui);letter-spacing:0;text-transform:none;white-space:nowrap;
  color:var(--fg-2);background:var(--bg-input);border:1px solid var(--border); }
.nt-type-app{ color:#22526A;background:color-mix(in srgb,#22526A 10%,transparent);border-color:color-mix(in srgb,#22526A 28%,transparent); }
.nt-type-domain{ color:#0E7C86;background:color-mix(in srgb,#0E7C86 10%,transparent);border-color:color-mix(in srgb,#0E7C86 28%,transparent); }
.nt-type-subdomain{ color:#5B3FA8;background:color-mix(in srgb,#5B3FA8 10%,transparent);border-color:color-mix(in srgb,#5B3FA8 28%,transparent); }
.nt-type-as-shell{ color:#22526A;border-color:color-mix(in srgb,#22526A 30%,transparent); }
.nt-type-as-template{ color:#6D5BD0;border-color:color-mix(in srgb,#6D5BD0 34%,transparent); }
.nt-type-as-form{ color:#A7640C;border-color:color-mix(in srgb,#C77B12 36%,transparent); }
.nt-type-as-component{ color:#0E7C86;border-color:color-mix(in srgb,#0E7C86 32%,transparent); }
.nt-type-as-icon{ color:#9A5B8F;border-color:color-mix(in srgb,#9A5B8F 34%,transparent); }
html[data-theme="dark"] .nt-type-app{ color:#8fc3d8; }
html[data-theme="dark"] .nt-type-domain, html[data-theme="dark"] .nt-type-as-component{ color:#5fd0d6; }
html[data-theme="dark"] .nt-type-subdomain, html[data-theme="dark"] .nt-type-as-template{ color:#b3a6ff; }
html[data-theme="dark"] .nt-type-as-form{ color:#f0b35e; }
html[data-theme="dark"] .nt-type-as-icon{ color:#e0a3d4; }
html[data-theme="dark"] .nt-type-as-shell{ color:#8fc3d8; }
.fe-pv-sel .nt-type{ flex:0 0 auto; }
/* the open-in-Assets shortcut stays, quieter than the row it sits on */
.nt-as-open{ opacity:0;width:26px;height:26px; }
.nt-as-box:hover .nt-as-open, .nt-as-box:focus-within .nt-as-open, .nt-as-box.is-sel .nt-as-open{ opacity:.8; }
@media (pointer:coarse){ .nt-as-open{ opacity:.7; } }
/* the row the preview is pointing at: the SAME animated gradient border the
   preview draws around the element (asset-map.js rings) */
.nt-as-box.is-hot{ position:relative;border-color:transparent;border-style:solid;background:var(--accent-soft); }
.nt-as-box.is-hot::after{ content:'';position:absolute;inset:-2px;border-radius:inherit;padding:2px;pointer-events:none;
  background:linear-gradient(90deg,var(--accent,#03C9CB),#7A5CFA,#FF9F45,var(--accent,#03C9CB));background-size:300% 100%;
  animation:ntHotRing 2.6s linear infinite;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude; }
@keyframes ntHotRing{ to{ background-position:300% 0; } }
@media (prefers-reduced-motion:reduce){ .nt-as-box.is-hot::after{ animation:none; } }
/* Styles: what the open design system has not styled — the box itself (red
   outline) and every box above it that holds one (so you can drill to it) */
.nt-box.is-unstyled{ border-color:var(--mk-danger,#e5484d) !important;border-style:solid;box-shadow:0 0 0 1px var(--mk-danger,#e5484d); }
.nt-box.has-unstyled{ border-color:color-mix(in srgb,var(--mk-danger,#e5484d) 70%,transparent) !important; }
.nt-need-n{ flex:0 0 auto;min-width:20px;height:19px;padding:0 6px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;
  background:var(--mk-danger,#e5484d);color:#fff;font:700 10.5px var(--mk-font-ui); }
.nt-box .nt-need-n{ margin-inline-start:auto; }
.nt-box .nt-need-n + .nt-acts{ margin-inline-start:6px; }

/* ═══ B64-Q2 — Frontend inspector on phones/tablets ══════════════════════
   Pablo: "the preview should be visible from the start and a collapsed bottom
   bar (or side bar in landscape) for the elements (panel) […] It's only when I
   release that the panel box would expand (as a bottom sheet in portrait and
   side panel in landscape) with the element I selected highlighted". Tapping
   an asset row opens the preview full-screen; the asset elements live in a
   collapsed bar; press-drag scans the page (asset-map.js), lifting the finger
   raises the sheet on what was picked. */
.fe-pv-x{ display:none;margin-inline-start:auto;width:36px;height:36px;border-radius:10px;border:1px solid var(--border);background:var(--bg-input);color:var(--fg-1);align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto; }
.fe-sheet{ display:none; }
@media (max-width:1099px){
  .fe-pv-col.fe-insp-on{ display:flex;position:fixed;inset:0;z-index:1500;top:0;height:auto;min-height:0;border-radius:0;border:0;padding:10px 12px 0;background:var(--bg-1); }
  .fe-pv-col.fe-insp-on .fe-pv-x{ display:inline-flex; }
  .fe-pv-col.fe-insp-on .fe-pv-stage{ flex:1;min-height:0;margin-bottom:84px; }
  .fe-pv-col.fe-insp-on .pvs-stage{ padding:12px 8px 8px; }
  /* Details on a phone/tablet: the same sheet grammar as the elements bar —
     a bottom sheet in portrait (a side sheet in landscape) over the preview */
  .fe-pv-col.fe-insp-on.fe-has-details .fe-pv-stage{ flex:1 1 auto; }
  .fe-pv-col.fe-insp-on.fe-has-details .fe-details{ position:absolute;inset-inline:0;bottom:0;z-index:3;height:min(78dvh, calc(100dvh - 70px));
    border-radius:20px 20px 0 0;overflow:hidden;box-shadow:0 -14px 40px -12px rgba(13,37,48,.35); }
  .fe-pv-col.fe-insp-on.fe-has-details .fe-details > .route-edit-panel.rt-docked{ border-radius:20px 20px 0 0;border-bottom:0; }
  .fe-pv-col.fe-insp-on.fe-has-details .fe-sheet{ display:none; }
  body.fe-insp-open{ overflow:hidden; }
  .fe-sheet{ display:flex;flex-direction:column;position:absolute;inset-inline:0;bottom:0;z-index:2;height:76px;overflow:hidden;
    background:var(--bg-1);border-top:1px solid var(--border);border-radius:20px 20px 0 0;box-shadow:0 -14px 40px -12px rgba(13,37,48,.35);
    transition:height .3s cubic-bezier(.32,.72,.28,1); }
  .fe-sheet.open{ height:min(62dvh, calc(100dvh - 90px)); }
  .fe-sheet-grab{ flex:0 0 auto;height:22px;border:0;background:none;position:relative;cursor:pointer; }
  .fe-sheet-grab::after{ content:'';position:absolute;top:8px;inset-inline-start:50%;transform:translateX(-50%);width:40px;height:4px;border-radius:999px;background:var(--border); }
  .fe-sheet-body{ flex:1;min-height:0;overflow:auto;padding:0 14px 16px;display:flex;flex-direction:column;gap:10px; }
}
@media (max-height:599px) and (orientation:landscape){
  .fe-pv-col.fe-insp-on .fe-pv-stage{ margin-bottom:0;margin-inline-end:70px; }
  .fe-pv-col.fe-insp-on.fe-has-details .fe-details{ inset-inline:auto 0;top:0;bottom:0;height:auto;width:min(460px, 60vw);border-radius:0; }
  .fe-pv-col.fe-insp-on.fe-has-details .fe-details > .route-edit-panel.rt-docked{ border-radius:0; }
  .fe-sheet{ inset-inline:auto 0;top:0;bottom:0;height:auto;width:64px;border-top:0;border-inline-start:1px solid var(--border);border-radius:0;flex-direction:row;
    transition:width .3s cubic-bezier(.32,.72,.28,1); }
  .fe-sheet.open{ width:min(420px, 56vw);height:auto; }
  .fe-sheet-grab{ width:22px;height:auto; }
  .fe-sheet-grab::after{ top:50%;inset-inline-start:9px;transform:translateY(-50%);width:4px;height:40px; }
  .fe-sheet-body{ padding:12px 12px 12px 4px; }
  .fe-sheet:not(.open) .fe-sheet-body{ visibility:hidden; }
}
.fe-sh-hint{ display:flex;align-items:center;gap:10px;font:500 12.5px/1.45 var(--mk-font-ui);color:var(--fg-2); }
.fe-sh-hint .mi{ font-size:22px;color:var(--accent-text); }
.fe-sh-crumb{ display:flex;flex-wrap:wrap;gap:4px;align-items:center; }
.fe-sh-crumb .fe-cr{ cursor:pointer; }
.fe-sh-sel{ display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px;border-radius:12px;border:1px solid var(--accent);background:var(--accent-soft); }
.fe-sh-sel b{ font:700 14px var(--mk-font-ui); }
.fe-sh-sel .nt-ic{ width:26px;height:26px;font-size:16px; }
.fe-sh-tree{ margin-inline-start:auto; }
.fe-sh-kids{ display:flex;flex-direction:column;gap:6px; }
.fe-sh-kid{ display:flex;align-items:center;gap:8px;min-height:44px;padding:6px 10px;border-radius:11px;border:1px dashed var(--border);background:var(--bg-1);color:var(--fg-1);cursor:pointer;text-align:start; }
.fe-sh-kid .nt-ic{ width:24px;height:24px;font-size:15px; }
.fe-sh-kn{ flex:1;min-width:0;font:600 13px var(--mk-font-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.fe-sh-go{ color:var(--fg-3); }

/* ═══ Audit A · B63-045 — sub-tickets ═══════════════════════════════════════ */
.gantt-row-sub > .gantt-lane{ padding-inline-start:calc(12px + var(--sub-d,1) * 18px); }
.gantt-row-sub > .gantt-lane::before{ content:'';position:absolute;inset-block:0;inset-inline-start:calc(4px + var(--sub-d,1) * 18px);width:2px;background:var(--border); }
.gantt-row-sub > .gantt-lane{ position:relative; }
.gantt-sub-tw{ flex:0 0 auto; }
.gantt-sub-tw[aria-expanded="true"] .mi{ transform:rotate(90deg); }
html[dir="rtl"] .gantt-sub-tw[aria-expanded="false"] .mi{ transform:scaleX(-1); }
.gantt-sub-n{ display:inline-flex;align-items:center;gap:2px;flex:0 0 auto;padding:1px 6px;border-radius:999px;background:var(--bg-input);border:1px solid var(--border);
  font:700 10.5px var(--mk-font-ui);color:var(--fg-2); }
.gantt-sub-n .mi{ font-size:12px; }
.gantt-sub-ic{ font-size:12px;vertical-align:-2px;margin-inline-end:2px; }
.gantt-vcard-hd .gantt-sub-n{ margin-inline-start:auto; }
.kb-sub-of,.kb-sub-n{ display:inline-flex;align-items:center;gap:2px;margin-inline-start:6px;padding:0 6px;border-radius:999px;
  background:var(--bg-input);border:1px solid var(--border);font:700 10px/16px var(--mk-font-ui);color:var(--fg-2);vertical-align:middle; }
.kb-sub-of .mi,.kb-sub-n .mi{ font-size:12px; }
.tk-subs{ display:flex;flex-direction:column;gap:6px; }
.tk-sub-row{ width:100%;display:flex;align-items:center;gap:10px;text-align:start;cursor:pointer; }
.tk-sub-ic{ font-size:18px;color:var(--fg-2);flex:0 0 auto; }
/* Audit A — accessibility #1, "no cropped critical info": on a phone a money
   row gave its NAME whatever width the avatars, the currency chip and the
   amount left over ("Cabl…", a trip tag wrapping over three lines). The name
   and the amount keep the first line; who and the currency drop to a second. */
@media (max-width:600px){
  .wl-row:has(> .wl-row-main):has(> .wl-amt){ display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:11px;row-gap:6px;align-items:center; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) > .wl-ic{ grid-column:1;grid-row:1 / span 2;align-self:start; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) > .wl-row-main{ grid-column:2;grid-row:1; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) > .wl-amt{ grid-column:3;grid-row:1;justify-self:end; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) > .wl-avs{ grid-column:2;grid-row:2;justify-self:start; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) > .wl-cur{ grid-column:3;grid-row:2;justify-self:end; }
  .wl-row:has(> .wl-row-main):has(> .wl-amt) .wl-row-nm{ white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical; }
}

/* B64 S1 — one chat everywhere: the forwarded label, and a chat mounted in a panel */
.mb-fwd{ display:flex;align-items:center;gap:4px;margin-bottom:4px;font:600 11px/1.25 var(--mk-font-ui);opacity:.75; }
.mb-fwd > .mi{ font-size:14px; }
.wl-chat-slide .msg{ max-width:100%; }
.ent-slide > .thread-slide{ background:var(--bg-1); }
/* the mounted chat fills its slide: messages grow, the composer sits at the bottom */
.panel-body > .wl-chat-slide{ min-height:100%; }
.wl-chat-slide > .wl-chat-msgs{ flex:1 1 auto; }
.mb-del{ display:inline-flex;align-items:center;gap:5px;font-style:italic;opacity:.7; }
.mb-del > .mi{ font-size:15px;font-style:normal; }
.msg.me .mb.mb-del{ background:var(--bg-2);color:var(--fg-2); }
.mt-ed{ font-style:italic;opacity:.8; }
.wl-chat-tools{ display:flex;justify-content:flex-end;position:sticky;top:-20px;z-index:3;margin:-6px 0 -4px; }
.wl-chat-tools > .ct-act{ background:var(--bg-1); }
.wl-chat-slide > .ct-search{ position:sticky;top:18px;z-index:3;background:var(--bg-1);border:1px solid var(--border);border-radius:10px; }

/* ── B65 W1 (065-082) — the wallet panel's in-place history ──────────────────
   The shell (header, footer) stays; only the body slides, like a pushed slide.
   Forward comes in from the trailing edge, Back from the leading edge. */
@keyframes wlViewFwd{ from{ transform:translateX(22%);opacity:0 } to{ transform:none;opacity:1 } }
@keyframes wlViewBack{ from{ transform:translateX(-22%);opacity:0 } to{ transform:none;opacity:1 } }
@keyframes wlViewFwdR{ from{ transform:translateX(-22%);opacity:0 } to{ transform:none;opacity:1 } }
@keyframes wlViewBackR{ from{ transform:translateX(22%);opacity:0 } to{ transform:none;opacity:1 } }
.wallet-panel [data-wl-body].wl-view-fwd{ animation:wlViewFwd .3s cubic-bezier(.32,.72,.28,1); }
.wallet-panel [data-wl-body].wl-view-back{ animation:wlViewBack .3s cubic-bezier(.32,.72,.28,1); }
html[dir="rtl"] .wallet-panel [data-wl-body].wl-view-fwd{ animation-name:wlViewFwdR; }
html[dir="rtl"] .wallet-panel [data-wl-body].wl-view-back{ animation-name:wlViewBackR; }
.wallet-panel.wl-has-hist > .panel-hd .panel-hd-l > .ent-hd-ic{ display:none; }
.wl-hist-back[hidden]{ display:none; }
@media (prefers-reduced-motion:reduce){ .wallet-panel [data-wl-body].wl-view-fwd, .wallet-panel [data-wl-body].wl-view-back{ animation:none; } }

/* B65 W2 (065-139) — a slide whose opening title repeated its own header keeps only
   the note that title carried (a count, a share, a date), as a quiet line. */
.wl-sech-note{ font:600 12px/1.4 var(--mk-font-ui);color:var(--fg-3);margin:2px 0 10px;font-variant-numeric:tabular-nums; }

/* B65 W7 (065-020) — a message TAG (a title chat: the episode it is about) on the
   bubble, and the tag bar above a tagged conversation's composer */
.mb-tag{ display:inline-flex;align-items:center;gap:4px;margin:0 0 5px;padding:2px 8px 2px 6px;border-radius:999px;
  font:700 10.5px/1.5 var(--mk-font-ui);letter-spacing:.02em;background:color-mix(in srgb,currentColor 12%,transparent);width:max-content;max-width:100%; }
.mb-tag > .mi{ font-size:13px; }
.mb > .mb-tag{ display:flex; }
.cmp-tagbar{ display:flex;align-items:center;gap:8px;padding:0 2px 8px;min-width:0; }
.cmp-tagbar-l{ display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;font:700 11px var(--mk-font-ui);color:var(--fg-3);text-transform:uppercase;letter-spacing:.06em; }
html[lang^="ar"] .cmp-tagbar-l{ letter-spacing:0; }
.cmp-tagbar-l > .mi{ font-size:15px;color:var(--accent-text,var(--accent)); }
.cmp-tagbar .cs{ min-width:120px;max-width:220px; }

/* ── B65 W8 — Buraco in Mocca: status, invitations, meld side, per-pair marking ── */
.bu-live{ gap:6px; }
.bu-live-dot{ width:7px;height:7px;border-radius:50%;background:currentColor;box-shadow:0 0 0 3px color-mix(in srgb,currentColor 22%,transparent);flex:0 0 auto; }
.bu-acts{ display:flex;flex-wrap:wrap;gap:8px;margin:12px 0 4px; }
.bu-acts .bu-act{ margin:0; }
.bu-sides{ display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:10px; }
.bu-side{ border:1px solid var(--bd-1,#dfe4e8);border-radius:12px;background:var(--bg-1,#fff);padding:10px 12px;display:flex;flex-direction:column;gap:8px;min-width:0; }
.bu-side-h{ display:flex;align-items:center;gap:8px; }
.bu-side-nm{ flex:1;min-width:0;font:700 13px/1.2 var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.bu-mark{ display:inline-flex;align-items:center;gap:4px;font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);padding:4px 8px;border-radius:999px;background:var(--bg-2,#f4f6f8);flex:0 0 auto; }
.bu-mark .mi{ font-size:14px; }
.bu-mark.is-done{ color:var(--mk-ok,#2f9e63);background:color-mix(in srgb,var(--mk-ok,#2f9e63) 12%,transparent); }
.bu-person{ display:flex;align-items:center;gap:8px;min-width:0; }
.bu-person-nm{ flex:1;min-width:0;font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.bu-person-nm em{ font-style:normal;font-weight:700;font-size:10.5px;color:var(--fg-3); }
.bu-pst{ display:inline-flex;align-items:center;gap:3px;font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);flex:0 0 auto; }
.bu-pst .mi{ font-size:14px; }
.bu-pst.is-in{ color:var(--mk-ok,#2f9e63); } .bu-pst.is-pend{ color:var(--accent-text,var(--accent)); } .bu-pst.is-decl, .bu-pst.is-left{ color:var(--fg-3); }
.bu-av-open{ background:var(--bg-2,#f4f6f8) !important;color:var(--fg-3) !important;border:1px dashed var(--bd-1,#dfe4e8); }
.bu-av-open .mi{ font-size:14px; }
.bu-meld{ display:flex;align-items:center;flex-wrap:wrap;gap:6px;padding-top:8px;border-top:1px dashed var(--bd-1,#dfe4e8);font:600 12px/1.3 var(--mk-font-ui);color:var(--fg-2); }
.bu-meld .mi{ font-size:16px;color:var(--accent-text,var(--accent)); }
.bu-meld-l{ color:var(--fg-3); }
.bu-meld .cs{ flex:1 1 160px;min-width:0; }
.bu-meld-now{ flex-basis:100%;font:600 11px/1.2 var(--mk-font-ui);color:var(--fg-3); }
.bu-other{ display:flex;align-items:center;gap:8px;padding:9px 11px;margin-bottom:8px;border:1px dashed var(--bd-1,#dfe4e8);border-radius:11px; }
.bu-other-nm{ flex:1;min-width:0;font:600 12.5px/1.2 var(--mk-font-ui);color:var(--fg-2); }
.bu-sec-away{ font-style:normal;font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3); }
.bu-dt{ display:grid;grid-template-columns:1fr 1fr;gap:8px; }

/* ═══ B65 W9 — SHOP re-model: labels, thumbnails, gauges, the drill picker,
   combo choices, the simple grocery list (065-130…159). Every icon here is a
   `.mi` on its own class — no element-type font rule near an icon. ═══════ */
.sh-label{ width:100%;text-align:start;cursor:pointer;align-items:center;gap:10px }
.sh-label.is-empty .wl-sumbox-t{ color:var(--fg-3);font-weight:600 }
.sh-label:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sh-label-ic{ font-size:20px;color:var(--fg-2) }
.sh-label-langs{ display:flex;align-items:center;gap:4px;margin-top:3px }
.sh-lang{ font:800 9.5px/1 var(--mk-font-ui);letter-spacing:.04em;padding:3px 5px;border-radius:5px;background:var(--bg-2);color:var(--fg-3) }
.sh-lang.on{ background:var(--accent-soft);color:var(--accent-text,var(--accent)) }
.sh-label-n{ font:700 10.5px/1 var(--mk-font-ui);color:var(--fg-3);margin-inline-start:4px }
.sh-label.wl-req, .sh-pick.wl-req{ border-color:var(--mk-danger,#C81E1E) }
/* a SKU's photo, or its brand's logo on a white plate */
.sh-thumb{ flex:0 0 auto;width:40px;height:40px;border-radius:10px;overflow:hidden;display:grid;place-items:center;
  background:#fff;border:1px solid var(--border) }
.sh-thumb img{ width:100%;height:100%;object-fit:contain;padding:12%;box-sizing:border-box;display:block }
.sh-thumb.is-photo img{ object-fit:cover;padding:0 }
.sh-thumb.sm, .sh-bmark.sm, .sh-mark.sm{ width:32px;height:32px;border-radius:9px }
.sh-thumb.xs, .sh-bmark.xs, .sh-mark.xs{ width:22px;height:22px;border-radius:6px;font-size:9px }
.sh-mark.xs .mi, .sh-bmark.xs .mi{ font-size:13px }
.sh-thumb.lg, .sh-mark.lg{ width:56px;height:56px;border-radius:14px }
.sh-mark.lg .mi{ font-size:26px }
.sh-thumb.xl, .sh-mark.xl{ width:88px;height:88px;border-radius:18px }
.sh-mark.xl .mi{ font-size:32px }
.sh-kv-brand{ display:inline-flex;align-items:center;gap:6px }
/* the made-here branch */
.ct-row.sh-made{ background:color-mix(in srgb,var(--accent) 5%,var(--bg-1)) }
/* 150 — gauges and dots instead of sentences */
.sh-gauge{ flex:0 0 auto;display:inline-flex;align-items:center;gap:6px }
.sh-gauge-bar{ width:64px;height:8px;border-radius:99px;background:var(--bg-2);overflow:hidden;box-shadow:inset 0 0 0 1px var(--border) }
.sh-gauge-bar i{ display:block;height:100%;border-radius:inherit;background:var(--mk-ok,#157F4C) }
.sh-dots{ display:inline-flex;gap:3px;min-width:0 }
.sh-dots i{ width:7px;height:7px;border-radius:50%;display:block }
.sh-dots i.low{ background:var(--mk-warning,#F59E0B) }
.sh-dots i.out{ background:var(--mk-danger,#C81E1E) }
.sh-health{ flex:0 0 auto;display:inline-flex;align-items:center;gap:7px }
.sh-hbar{ display:flex;width:72px;height:8px;border-radius:99px;overflow:hidden;gap:2px }
.sh-hbar i{ display:block;height:100%;min-width:6px }
.sh-hbar i.ok{ background:var(--mk-ok,#157F4C) }
.sh-hbar i.low{ background:var(--mk-warning,#F59E0B) }
.sh-hbar i.out{ background:var(--mk-danger,#C81E1E) }
.sh-hbar i.none{ background:var(--bg-2) }
.sh-hn{ font:800 12px/1 var(--mk-font-ui);color:var(--fg-2);font-variant-numeric:tabular-nums;min-width:14px;text-align:end }
.sh-lvl{ flex:0 0 auto;display:inline-flex;align-items:center;gap:8px }
.sh-lvl-bar{ position:relative;width:72px;height:8px;border-radius:99px;background:var(--bg-2);box-shadow:inset 0 0 0 1px var(--border) }
.sh-lvl-bar i{ position:absolute;inset-inline-start:0;top:0;bottom:0;border-radius:inherit;background:var(--mk-ok,#157F4C) }
.sh-lvl.is-low .sh-lvl-bar i{ background:var(--mk-warning,#F59E0B) }
.sh-lvl.is-out .sh-lvl-bar i{ background:var(--mk-danger,#C81E1E) }
.sh-lvl-mk{ position:absolute;inset-inline-start:50%;top:-3px;bottom:-3px;width:2px;border-radius:2px;background:var(--fg-2);opacity:.55 }
.sh-lvl-n{ font:800 12.5px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums;min-width:48px;text-align:end;white-space:nowrap }
.sh-lvl-n small{ font:600 10px/1 var(--mk-font-ui);color:var(--fg-3) }
.sh-lvl.is-out .sh-lvl-n{ color:var(--mk-danger,#C81E1E) }
.sh-lvl.is-big .sh-lvl-bar{ width:160px;height:12px }
.sh-lvl.is-big .sh-lvl-n{ font-size:22px;min-width:0 }
.sh-lvl.is-big .sh-lvl-n small{ font-size:12px }
.sh-line-hd{ justify-content:flex-start }
.sh-line-hd-m{ display:flex;flex-direction:column;align-items:flex-start;gap:8px;min-width:0 }
.sh-loc-hd, .sh-unit-hd{ display:flex;align-items:center;flex-wrap:wrap;gap:14px;margin:0 0 12px;padding:12px;border-radius:12px;background:var(--bg-2) }
.sh-unit-hd .sh-gauge-bar{ width:120px;height:10px }
.sh-unit-n{ display:inline-flex;align-items:baseline;gap:5px;font:600 12px/1 var(--mk-font-ui);color:var(--fg-2) }
.sh-unit-n b{ font:800 18px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.sh-unit-n.is-low b{ color:var(--mk-warn,#8A6100) }
.sh-unit-n.is-out b{ color:var(--mk-danger,#C81E1E) }
.sh-acts-2{ display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 6px }
.sh-acts-2 .wl-close-btn{ display:inline-flex;align-items:center;gap:6px }
.sh-ro{ display:inline-flex;align-items:center;gap:5px;font-variant-numeric:tabular-nums }
.sh-ro .mi{ font-size:14px;color:var(--fg-3) }
/* movements */
.sh-moves{ display:flex;flex-direction:column;gap:4px }
.sh-move{ display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:10px;border:1px solid var(--border);background:var(--bg-1) }
.sh-move .mi{ font-size:18px;color:var(--fg-2) }
.sh-move.is-order .mi{ color:var(--accent-text,var(--accent)) }
.sh-move.is-receipt .mi{ color:var(--mk-ok,#157F4C) }
.sh-move-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px }
.sh-move-t{ font:600 12.5px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.sh-move-s{ font:500 11px/1.2 var(--mk-font-ui);color:var(--fg-3);font-variant-numeric:tabular-nums }
.sh-move-d{ font:800 13px/1 var(--mk-font-ui);color:var(--mk-ok,#157F4C);font-variant-numeric:tabular-nums }
.sh-move-d.is-neg{ color:var(--mk-danger,#C81E1E) }
.sh-move-d.is-soft{ color:var(--fg-3) }
/* stock count */
.sh-count{ display:flex;flex-direction:column;gap:6px }
.sh-count-row{ display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--border);border-radius:11px;background:var(--bg-1) }
.sh-count-row .wl-sumbox-main{ flex:1;min-width:0 }
.sh-count-row b.is-neg{ color:var(--mk-danger,#C81E1E) }
.sh-count-row b.is-pos{ color:var(--mk-ok,#157F4C) }
/* the −n+ stepper (count, groceries, combo picks) */
.sh-step{ flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;border:1px solid var(--border);border-radius:10px;background:var(--bg-1);padding:2px }
.sh-step button{ width:32px;height:32px;aspect-ratio:1;display:grid;place-items:center;padding:0;border:0;border-radius:8px;background:transparent;color:var(--fg-1);cursor:pointer }
.sh-step button:hover:not(:disabled){ background:var(--bg-2) }
.sh-step button:disabled{ opacity:.35;cursor:default }
.sh-step button .mi{ font-size:18px }
.sh-step b{ min-width:26px;text-align:center;font:800 14px/1 var(--mk-font-ui);font-variant-numeric:tabular-nums;color:var(--fg-1) }
.sh-step input{ width:64px;text-align:center;padding:6px 4px }
/* the chosen value as a chip (146) */
.sh-pick{ width:100%;display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--border);border-radius:12px;
  background:var(--bg-1);color:var(--fg-1);cursor:pointer;text-align:start }
.sh-pick:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sh-pick.is-empty{ border-style:dashed;color:var(--fg-2) }
.sh-pick-m{ flex:1;min-width:0;display:flex;flex-direction:column;gap:2px }
.sh-pick-t{ font:700 13px/1.25 var(--mk-font-ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.sh-pick-s{ font:500 11.5px/1.2 var(--mk-font-ui);color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.sh-pick-go{ font-size:18px;color:var(--fg-3) }
/* the drill (the field-path way) */
.sh-drill{ display:flex;flex-direction:column;gap:10px }
.sh-drill-q{ display:flex;align-items:center;gap:8px;padding:0 10px;border:1px solid var(--border);border-radius:11px;background:var(--bg-1) }
.sh-drill-q .mi{ font-size:18px;color:var(--fg-3) }
.sh-drill-q .ent-input{ border:0;background:transparent;padding-inline:0;box-shadow:none }
.sh-crumbs{ display:flex;align-items:center;flex-wrap:wrap;gap:4px }
.sh-crumbs .wl-chip.on{ border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text,var(--accent)) }
.sh-crumb-sep{ font-size:16px;color:var(--fg-3) }
[dir="rtl"] .sh-crumb-sep{ transform:scaleX(-1) }
.sh-drill-list{ display:flex;flex-direction:column;gap:6px }
.sh-drill-row{ width:100%;text-align:start;cursor:pointer;align-items:center;gap:10px }
.sh-drill-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sh-drill-row.is-leaf .wl-ctc-go{ color:var(--accent-text,var(--accent)) }
/* photo editor */
.sh-photo-ed{ display:flex;align-items:center;gap:14px;flex-wrap:wrap }
.sh-rooms{ display:flex;flex-wrap:wrap;gap:6px }
.sh-rooms .wl-chip.on{ border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text,var(--accent)) }
/* ingredients (derived) and nutrition, as tiles */
.sh-ingr{ display:flex;flex-wrap:wrap;gap:6px;margin:4px 0 10px }
.sh-ingr-c{ padding:5px 9px;border-radius:8px;background:var(--bg-2);font:600 12px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.sh-ingr-c small{ color:var(--fg-3);font-weight:600 }
.sh-nut{ display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:6px;margin:4px 0 4px }
.sh-nut-c{ display:flex;flex-direction:column;gap:4px;padding:9px 10px;border-radius:10px;border:1px solid var(--border);background:var(--bg-1) }
.sh-nut-c b{ font:800 16px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.sh-nut-c b small{ font:600 10.5px/1 var(--mk-font-ui);color:var(--fg-3);margin-inline-start:2px }
.sh-nut-c > span{ font:600 11px/1.2 var(--mk-font-ui);color:var(--fg-2) }
.sh-nut-per{ font:500 11px/1.2 var(--mk-font-ui);color:var(--fg-3);margin:0 0 10px }
/* 135 — an allergen is information: neutral, small, no warning sign */
.sh-allergens{ display:inline-flex;flex-wrap:wrap;gap:4px;vertical-align:middle }
.sh-allergen{ display:inline-flex;align-items:center;padding:2px 7px;border-radius:99px;vertical-align:middle;
  border:1px solid var(--border);background:transparent;font:600 10.5px/1.4 var(--mk-font-ui);color:var(--fg-2) }
.wl-sumbox-main .sh-allergens{ margin-top:4px }
/* Menu */
.mn-preps{ display:flex;flex-direction:column;gap:8px }
.mn-row{ cursor:pointer;align-items:center }
.mn-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-step-ic{ font-size:18px;color:var(--fg-2);flex:0 0 auto }
.mn-item-hd{ display:flex;align-items:center;gap:10px;margin:0 0 12px }
.mn-item-price{ margin-inline-start:auto;font:800 18px/1 var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums }
.mn-group{ padding:10px 12px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1);margin:0 0 8px }
.mn-group.is-fixed{ background:var(--bg-2);border-style:dashed }
.mn-group-h{ display:flex;align-items:center;gap:8px;margin:0 0 8px }
.mn-group-h .mi{ font-size:16px;color:var(--fg-2) }
.mn-group-n{ flex:0 0 auto;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent-text,var(--accent));font:800 12px/1 var(--mk-font-ui) }
.mn-group-t{ font:700 13px/1.25 var(--mk-font-ui);color:var(--fg-1) }
.mn-group-s{ margin-inline-start:auto;font:600 11px/1 var(--mk-font-ui);color:var(--fg-3) }
.mn-opts{ display:flex;flex-wrap:wrap;gap:6px;align-items:center }
.mn-opt{ display:inline-flex;align-items:center;gap:6px;padding:4px 9px 4px 4px;border-radius:99px;border:1px solid var(--border);background:var(--bg-1);
  font:600 12px/1.2 var(--mk-font-ui);color:var(--fg-1);cursor:pointer }
.mn-opt[data-sh-push]:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.mn-opt .sh-mark.xs, .mn-opt .sh-thumb.xs, .mn-opt .sh-bmark.xs{ border-radius:50% }
.mn-opt-up{ font:700 11px/1 var(--mk-font-ui);color:var(--accent-text,var(--accent));font-variant-numeric:tabular-nums }
.mn-opt-x{ width:20px;height:20px;display:grid;place-items:center;padding:0;border:0;border-radius:50%;background:transparent;color:var(--fg-3);cursor:pointer }
.mn-opt-x .mi{ font-size:14px }
.mn-step-open{ flex:1;min-width:0;display:flex;align-items:center;gap:10px;padding:0;border:0;background:transparent;color:inherit;text-align:start;cursor:pointer }
.mn-step-open .mi{ font-size:18px;color:var(--fg-2) }
.mn-steps-ed, .mn-groups-ed{ margin:0 0 4px }
.mn-opt-ed{ display:flex;flex-direction:column;gap:6px }
.mn-opt-row{ display:flex;align-items:center;gap:10px;padding:7px 10px;border:1px solid var(--border);border-radius:11px;background:var(--bg-1) }
.mn-opt-row .wl-sumbox-main{ flex:1;min-width:0 }
.mn-up{ display:inline-flex;align-items:center;gap:4px;font:700 12px/1 var(--mk-font-ui);color:var(--fg-2) }
.mn-up .ent-input{ width:92px }
/* Groceries — the simple list (157) */
.gr-list{ display:flex;flex-direction:column;gap:8px }
.gr-row{ gap:10px }
.gr-row .sh-mark.sm{ flex:0 0 auto }
.gr-group{ display:inline-flex;align-items:center;gap:3px;margin-inline-start:6px;padding:2px 7px;border-radius:99px;vertical-align:middle;
  background:var(--bg-2);font:700 10px/1.3 var(--mk-font-ui);color:var(--fg-2);text-decoration:none }
.gr-group .mi{ font-size:12px }
.gr-ladder{ white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.gr-line-hd{ display:flex;align-items:center;gap:12px;margin:0 0 14px }
.gr-line-hd-m{ flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:5px }
.gr-line-t{ font:700 16px/1.2 var(--mk-font-ui);color:var(--fg-1) }
.gr-line-hd .gr-group{ margin:0 }
.gr-rule{ gap:8px }
.gr-rule-open{ flex:1;min-width:0;display:flex;align-items:center;gap:8px;padding:0;border:0;background:transparent;color:inherit;text-align:start;cursor:pointer }
.gr-match{ display:inline-flex;align-items:center;gap:3px }
.gr-match > span:last-child{ margin-inline-start:4px }
.gr-match.is-none{ color:var(--fg-3) }
.gr-any{ display:flex;align-items:center;gap:8px }
.gr-any .mi{ font-size:18px;color:var(--mk-ok,#157F4C) }
.gr-rule-ed{ display:flex;flex-direction:column;gap:10px }
.gr-fits{ display:flex;flex-direction:column;gap:6px }
.gr-fit{ align-items:center;gap:10px }
@media (max-width: 560px){
  .sh-gauge-bar, .sh-hbar, .sh-lvl-bar{ width:44px }
  .sh-lvl-n{ min-width:40px }
  .sh-lvl.is-big .sh-lvl-bar{ width:120px }
  .gr-row .sh-mark.sm{ display:none }
  .ct-row.sh-row .sh-dots{ display:none }
}
/* a plain, visible checkbox row (the Shop forms) */
.sh-ck{ display:flex;align-items:center;gap:10px;min-height:40px;padding:6px 10px;border:1px solid var(--border);border-radius:10px;
  background:var(--bg-1);cursor:pointer;font:600 13px/1.3 var(--mk-font-ui);color:var(--fg-1) }
.sh-ck input{ flex:0 0 auto;width:18px;height:18px;margin:0;accent-color:var(--accent);cursor:pointer }
.sh-ck:has(input:checked){ border-color:color-mix(in srgb,var(--accent) 42%,var(--border));background:var(--accent-soft) }
/* 151–156 — a wordmark needs width: brand cards and the brand panel show the
   logo on a wider plate (monograms stay square) */
.sh-brand .sh-bmark.has-logo{ width:72px;height:44px }
.sh-brand .sh-bmark.has-logo img{ padding:8% 10% }
.sh-sku-hd .sh-bmark.has-logo.lg, .sh-logo-ed .sh-bmark.has-logo.lg{ width:96px }
.gr-row .wl-sumbox-t{ white-space:normal;overflow:visible }
.sh-move-d, .sh-lvl-n, .sh-count-row b, .sh-hn, .mn-opt-up, .mn-item-price{ direction:ltr;unicode-bidi:isolate }

/* B65 W11 (065-088) — "Add user" opens the multi-select straight from its own button: the trigger
   of the hosted select is invisible, the button under it stays the visible control. */
.rg-add-host .cs{ display:block;width:100%;height:100%; }
.rg-add-host .cs-btn{ opacity:0;pointer-events:none;height:100%;min-height:0;padding:0;border:0; }
.rg-add-host .cs-menu{ min-width:280px; }
.ci-sec .ct-rows{ display:flex;flex-direction:column;gap:6px; }

/* ══ B65 W12 — Calendar: period stepper, recurrence marks, the event panel ══ */
/* 065-100/102 — ‹ Today › under the title, the Timeline stepper's own buttons. */
.cal-period{ display:flex;align-items:center;flex-wrap:wrap;gap:4px 6px;margin-top:6px; }
.cal-today{ height:30px;padding:0 12px;border-radius:8px;border:1px solid var(--border);background:var(--bg-input);
  font:600 12.5px var(--mk-font-ui);color:var(--fg-1);cursor:pointer;transition:border-color var(--mk-t-fast),color var(--mk-t-fast); }
.cal-today:hover{ border-color:var(--accent);color:var(--accent-text); }
.cal-today.is-now{ color:var(--fg-3); }
.cal-period-lbl{ margin-inline-start:6px;font:600 13px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.cal-period-n{ font:500 13px var(--mk-font-ui);color:var(--fg-2); }
:root[dir="rtl"] .cal-period .gantt-step .mi{ transform:scaleX(-1); }
@media (pointer:coarse){ .cal-period .gantt-step,.cal-today{ height:40px;min-width:40px; } }
.cal-empty{ display:flex;align-items:center;gap:8px;padding:10px 12px;margin-bottom:8px;border:1px dashed var(--border);
  border-radius:var(--mk-radius-md);font:600 12.5px var(--mk-font-ui);color:var(--fg-3); }
.cal-empty .mi{ font-size:18px; }
/* 065-101 — recurring + frequency on the box itself, all three views. */
.ag-event .ae-t,.wk-event .we-t{ display:flex;align-items:center;gap:6px;min-width:0; }
.ag-event .ae-tt,.wk-event .we-tt{ min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ev-rep{ flex:0 0 auto;display:inline-flex;align-items:center;gap:2px;padding:1px 6px 1px 4px;border-radius:var(--mk-radius-pill);
  background:color-mix(in srgb,currentColor 10%,transparent);color:var(--fg-2);font:600 10px/1.3 var(--mk-font-ui); }
.ev-rep .mi{ font-size:12px; }
.wk-event .ev-rep{ padding:0 5px 0 3px;font-size:9.5px; }
.mo-ev .ev-rep{ padding:0;background:none;color:inherit;opacity:.75; }
.mo-ev .ev-rep .mi{ font-size:11px; }
.ag-event.is-past,.wk-event.is-past{ opacity:.78; }
.mo-ev.is-past{ opacity:.75; }
/* The event panel (MoccaPanel · .ev-panel) — rows that push slides. */
.ev-panel .ev-sec{ display:flex;flex-direction:column;gap:6px;margin-top:16px; }
.ev-panel .ev-sec-h{ display:flex;align-items:center;gap:6px;font:700 11px var(--mk-font-ui);letter-spacing:.04em;color:var(--fg-3); }
.ev-panel .ev-sec-h .mi{ font-size:15px; }
.ev-panel .ev-acts{ flex-direction:row;flex-wrap:wrap;gap:8px; }
.ev-row{ display:flex;align-items:center;gap:10px;width:100%;min-height:48px;padding:8px 10px;text-align:start;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--mk-radius-md);background:var(--bg-1);color:var(--fg-1);
  transition:border-color var(--mk-t-fast),background var(--mk-t-fast); }
.ev-row:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border));background:color-mix(in srgb,var(--accent) 4%,var(--bg-1)); }
.ev-row-ic{ flex:0 0 auto;font-size:19px;color:var(--fg-2); }
.ev-row-b{ flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px; }
.ev-row-t{ font:600 13px var(--mk-font-ui);color:var(--fg-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ev-row-s{ font:500 11.5px var(--mk-font-ui);color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.ev-row-go{ flex:0 0 auto;font-size:18px;color:var(--fg-3); }
:root[dir="rtl"] .ev-row-go{ transform:scaleX(-1); }
.ev-row-add{ border-style:dashed; }
.ev-row-add .ev-row-t{ color:var(--fg-2);font-weight:600; }
.ev-row-pill{ flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;font:600 11px var(--mk-font-ui);color:var(--fg-2); }
.ev-row-pill .dot{ width:8px;height:8px;border-radius:50%; }
.ev-occ{ display:flex;align-items:center;gap:12px;width:100%;padding:8px 10px;text-align:start;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--mk-radius-md);background:var(--bg-1);color:var(--fg-1); }
.ev-occ:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)); }
.ev-occ.is-past{ background:var(--bg-2); }
.ev-occ.is-current{ cursor:default;border-color:var(--accent);background:color-mix(in srgb,var(--accent) 7%,var(--bg-1)); }
.ev-occ-d{ flex:0 0 42px;display:flex;flex-direction:column;align-items:center;line-height:1.1;font:600 10.5px var(--mk-font-ui);color:var(--fg-3);text-transform:capitalize; }
.ev-occ-d b{ font:700 17px var(--mk-font-ui);color:var(--fg-1);font-variant-numeric:tabular-nums; }
.ev-occ-b{ flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px; }
.ev-occ-t{ font:600 13px var(--mk-font-ui);text-transform:capitalize; }
.ev-occ-s{ display:inline-flex;align-items:center;gap:4px;font:500 11.5px var(--mk-font-ui);color:var(--fg-3); }
.ev-occ-s .mi{ font-size:14px; }
.ev-more{ align-self:flex-start;display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 12px;border:0;border-radius:var(--mk-radius-pill);
  background:var(--bg-2);color:var(--fg-2);font:600 12px var(--mk-font-ui);cursor:pointer; }
.ev-more:hover{ color:var(--accent-text); }
.ev-more .mi{ font-size:16px; }
.ev-sum{ margin:0;padding-inline-start:18px;display:flex;flex-direction:column;gap:5px;font:500 13px/1.45 var(--mk-font-ui);color:var(--fg-1); }
.ev-tr{ display:flex;flex-direction:column;gap:10px; }
.ev-tr-l{ display:grid;grid-template-columns:auto auto 1fr;gap:8px;align-items:start; }
.ev-tr-l b{ font:600 12.5px var(--mk-font-ui);color:var(--fg-1); }
.ev-tr-l p{ margin:2px 0 0;font:500 13px/1.45 var(--mk-font-ui);color:var(--fg-2); }
.ev-tr-tm{ font:600 11px var(--mk-font-mono);color:var(--fg-3);padding-top:3px;font-variant-numeric:tabular-nums; }
.ev-video{ position:relative;display:grid;place-items:center;aspect-ratio:16/9;border-radius:var(--mk-radius-lg);
  background:linear-gradient(135deg,color-mix(in srgb,var(--accent) 55%,#0A1A22),#0A1A22);color:#fff; }
.ev-video > .mi{ font-size:56px;opacity:.92; }
.ev-video-d{ position:absolute;inset-inline-end:10px;bottom:10px;padding:2px 7px;border-radius:6px;background:rgba(0,0,0,.55);
  font:600 11px var(--mk-font-ui);font-variant-numeric:tabular-nums; }
.ev-chat-body{ display:flex;flex-direction:column;min-height:0; }

/* ── B65 W13 (065-170) — contact reasons are configured: twist · row edits · + adds ── */
.sp-twist{ border:0;background:none;padding:0;cursor:pointer;color:inherit;width:24px;height:28px;display:inline-flex;align-items:center;justify-content:center;border-radius:7px }
.sp-twist:hover{ background:var(--bg-3) }
.sp-twist:focus-visible,.sp-add:focus-visible{ outline:2px solid var(--accent);outline-offset:1px }
.sp-add{ flex:0 0 auto;width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;margin-inline-start:auto }
.ct-row-n + .sp-add{ margin-inline-start:6px }
.sp-icons{ display:grid;grid-template-columns:repeat(auto-fill,minmax(40px,1fr));gap:6px }
.sp-ic{ height:40px;border-radius:10px;border:1px solid var(--border);background:var(--bg-2);color:var(--fg-2);display:inline-flex;align-items:center;justify-content:center;cursor:pointer }
.sp-ic:hover{ border-color:color-mix(in srgb,var(--accent) 45%,var(--border)) }
.sp-ic.on{ background:var(--accent-soft);border-color:var(--accent);color:var(--accent-text,var(--accent)) }
.sp-ic .mi{ font-size:20px }
.sp-opts{ display:flex;flex-wrap:wrap;gap:6px }
.sp-opt{ display:inline-flex;align-items:center;gap:5px }
.sp-opt .mi{ font-size:15px }
.sp-opt.on{ background:var(--accent-soft);border-color:var(--accent);color:var(--accent-text,var(--accent)) }
.wl-chip.is-danger{ color:var(--mk-danger,#C81E1E) }
.ent-input.is-invalid{ border-color:var(--mk-danger,#C81E1E) }

/* ── B65 W13 (065-173…177) — Companies: real profiles, scalable subsidiaries, full form ── */
.wl-co-flag-img{ width:18px;height:18px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-inline-end:6px;flex:0 0 auto }
.wl-co-ops{ display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px }
.wl-co-q{ margin:2px 0 10px }
.wl-co-grp{ display:flex;flex-direction:column;gap:6px;margin-bottom:12px }
.wl-co-grp[hidden],.wl-co-grp [hidden]{ display:none }
.wl-co-grp-h{ display:flex;align-items:center;gap:6px;font:700 12px/1.2 var(--mk-font-ui);color:var(--fg-2);padding:2px 2px 0 }
.wl-co-grp-h b{ margin-inline-start:auto;font-weight:700;color:var(--fg-3) }
.wl-co-inst[data-co-jump]{ cursor:pointer }
.wl-co-logo-pick{ display:flex;align-items:center;gap:12px }
.wl-co-logo-prev{ width:52px;height:52px;border-radius:12px;border:1px solid var(--border);background:var(--bg-2);display:inline-flex;align-items:center;justify-content:center;overflow:hidden;color:var(--fg-3);flex:0 0 auto }
.wl-co-logo-prev img{ width:100%;height:100%;object-fit:contain }
/* B66 W1 (066-086) — inside a folder the crumb bar IS the slide's header: ‹ back,
   the path, and the folder's name at the page title's size */
.page-view.mc-slide-open .dr-crumb{ position:sticky; top:0; z-index:15; background:var(--bg-0, var(--bg-1)); padding:18px 0 14px; margin:0 0 6px; gap:8px; }
.page-view.mc-slide-open .dr-crumb .dr-crumb-b{ font:600 14px var(--mk-font-ui); color:var(--fg-3); }
.page-view.mc-slide-open .dr-crumb .dr-crumb-b.is-cur{ font:700 22px var(--mk-font-ui); letter-spacing:-.015em; color:var(--fg-1); }
.co-empty{ margin:6px 2px; font:500 13px var(--mk-font-ui); color:var(--fg-3); }
/* B66 W7 (066-066 · 070) — the calendar's period stepper sits in the header's actions, like Timeline's */
.page-h .acts .cal-period{ margin-top:0;flex-wrap:nowrap;gap:2px; }
.cal-period .cal-period-lbl{ margin-inline-start:0;cursor:default;min-width:0;white-space:nowrap; }
.cal-period .cal-period-lbl:hover{ border-color:var(--border); }
.cal-period .cal-today{ margin-inline-start:6px; }
/* B66 W7 (066-069) — in a panel the chat's search lives in the header; the tools row is only the search bar's anchor */
.wl-chat-tools.is-empty{ height:0;margin:0;padding:0;overflow:visible; }
/* B66 W8 (066-073) — a product's variant types and the SKU matrix (one option per type) */
.sh-vts{ display:flex;flex-direction:column;gap:8px;margin:2px 0 10px; }
.sh-vt{ display:flex;align-items:flex-start;gap:12px;padding:10px 12px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1); }
.sh-vt > b{ flex:0 0 96px;font:700 13px/1.5 var(--mk-font-ui);color:var(--fg-1); }
.sh-vt-opts{ display:flex;flex-wrap:wrap;gap:6px;min-width:0;flex:1; }
.sh-vt-opt{ display:inline-flex;align-items:center;gap:4px;height:26px;padding:0 10px;border-radius:999px;background:var(--bg-2);border:1px solid var(--border);font:600 12px var(--mk-font-ui);color:var(--fg-2); }
.sh-vt-opt button{ border:0;background:none;padding:0;margin-inline-end:-4px;display:grid;place-items:center;color:var(--fg-3);cursor:pointer; }
.sh-vt-opt button .mi{ font-size:15px; }
.sh-none{ margin:4px 0 10px;font:500 13px var(--mk-font-ui);color:var(--fg-3); }
.sh-mx{ display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:6px;margin:2px 0 8px; }
.sh-mx-c{ display:flex;align-items:center;gap:6px;min-height:38px;padding:6px 10px;border-radius:10px;border:1px dashed var(--border-strong,var(--border));background:none;cursor:pointer;text-align:start;font:600 12px/1.3 var(--mk-font-ui);color:var(--fg-3); }
.sh-mx-c .mi{ font-size:16px; }
.sh-mx-c span:not(.mi){ flex:1;min-width:0; }
.sh-mx-c.on{ border-style:solid;border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text); }
.sh-mx-c b{ min-width:20px;height:20px;border-radius:999px;display:grid;place-items:center;background:var(--accent);color:var(--accent-fg,#fff);font:700 11px var(--mk-font-ui); }
.sh-mx-c:hover{ border-color:var(--accent);color:var(--fg-1); }
.sh-vted{ display:flex;flex-direction:column;gap:10px;align-items:flex-start; }
.sh-vt-ed{ width:100%;display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid var(--border);border-radius:12px;background:var(--bg-1); }
.sh-vt-ed-h{ display:flex;align-items:center;gap:6px; }
.sh-vt-ed-h .ent-input{ flex:1; }
.sh-vt-add{ width:150px;height:28px !important;min-height:28px !important; }
/* B66 W8 (066-077) — a preparation's Steps, read and edited (ranked by drag like its Ingredients) */
.mn-steps{ margin:4px 0 8px;padding-inline-start:22px;display:flex;flex-direction:column;gap:6px;font:500 13.5px/1.45 var(--mk-font-ui);color:var(--fg-1); }
.mn-instr-ed{ align-items:center; }
.mn-instr-n{ flex:none;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;background:var(--bg-2);font:700 11px var(--mk-font-ui);color:var(--fg-2); }
.mn-instr-ed .ent-input{ flex:1;min-width:0; }
.mn-tag.bad{ background:color-mix(in srgb,var(--mk-danger) 14%,transparent);color:var(--mk-danger); }
/* B66 W8 (066-078) — Stock › Locations: the Places tree beside the selected area's plan with its storage units */
.st-locs{ display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:16px;align-items:start; }
.st-plan{ position:sticky;top:76px;display:flex;flex-direction:column;gap:10px;padding:12px;border:1px solid var(--border);border-radius:var(--mk-radius-lg);background:var(--bg-1);box-shadow:0 10px 30px -22px rgba(13,37,48,.35); }
.st-plan-h{ display:flex;align-items:center;gap:6px;flex-wrap:wrap; }
.st-plan-h b{ font:700 14px var(--mk-font-ui);color:var(--fg-1); }
.st-plan-sp{ flex:1; }
.st-plan-h .wl-chip.on{ border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text); }
.st-plan-c{ border-radius:12px;background:repeating-linear-gradient(0deg,transparent 0 39px,var(--divider,var(--border)) 39px 40px),repeating-linear-gradient(90deg,transparent 0 39px,var(--divider,var(--border)) 39px 40px),var(--bg-2);padding:8px; }
.st-plan-c.is-placing{ cursor:crosshair;outline:2px dashed var(--accent);outline-offset:-2px; }
.st-plan-svg{ width:100%;height:auto;display:block; }
.st-plan-wall{ fill:var(--bg-1);stroke:var(--fg-2);stroke-width:3; }
.st-plan-u{ cursor:pointer; }
.st-plan-u rect:first-child{ stroke-width:2; }
.st-plan-u:hover rect:first-child, .st-plan-u:focus rect:first-child{ stroke-width:3; }
.st-plan-u text{ font:700 11px var(--mk-font-ui);fill:var(--fg-1);text-anchor:middle;pointer-events:none; }
@media (max-width:1099px){ .st-locs{ grid-template-columns:minmax(0,1fr); } .st-plan{ position:static; } }

/* B67 R21 (R67-079) — directional icons follow the reading direction in Arabic, as the rest of the app already does (Audit A:
   "forward points to the reading direction"; .ent-open · .pe-card-chev · .cal-period .gantt-step · .fp-back-btn …). Each was
   the only one of its kind still pointing the LTR way: "go" chevrons, forward/back arrows, prev/next steppers, crumbs, twists. */
html[dir="rtl"] .wl-ctc-go,
html[dir="rtl"] .fc-go,
html[dir="rtl"] .rt-box-caret,
html[dir="rtl"] .nt-rel-go,
html[dir="rtl"] .ct-twist:not(.is-leaf):not(.sh-twist),   /* .sh-twist mirrors its own .mi already */
html[dir="rtl"] .kb-sub-of .mi,
html[dir="rtl"] .gantt-sub-ic,
html[dir="rtl"] .wl-sub-ic,
html[dir="rtl"] .card-more-go,
html[dir="rtl"] .gantt-period .gantt-step .mi,
html[dir="rtl"] .wl-chip:is([data-dr-crumb="-1"], [data-fc-close], [data-su-close]) .mi{ transform:scaleX(-1); }

/* B67 R21 (R67-084) — closed / parked layers leave the Tab order (as R67-031 · 034): each only slid or faded away, so Tab
   walked into its controls unseen. Hidden once its own exit motion ends, visible at once when it opens. */
.gantt-link-hud{ visibility:hidden; transition:opacity var(--mk-t-fast), visibility 0s linear var(--mk-t-fast); }
.gantt-link-hud.on{ visibility:visible; transition:opacity var(--mk-t-fast), visibility 0s; }
