/* Aldar — design system from the Claude Design canvas (Aldar Dashboard.dc.html).
   Mobile-first: 320 → 390 → 834 → 1440. Light and dark are both first-class.
   Breakpoint ladder: 560 (forms) · 640 (stats) · 720 (tablet) · 840 · 1080 (desktop).

   TWO AXES, and they are independent:

   THEME. <html data-theme> is auto | light | dark, written by the server from the
   signed-in account. 'auto' follows the phone, which is all this sheet used to do.
   The dark tokens therefore appear twice - once inside prefers-color-scheme for
   the accounts that have not chosen, once outside it for the accounts that have.
   That duplication is the price of letting a person pin the light design on a
   phone that is set to dark, which is the whole point (his father works outdoors).

   DIRECTION. <html dir> is ltr or rtl. Layout uses logical properties, so almost
   nothing needs a [dir=rtl] rule; the handful that do are the things a browser
   cannot flip on its own - a physical box-shadow, a background gradient position,
   and the chevron on a card's action, which points the way the reader reads. */

:root{
  --bg:#EEE9DF; --panel:#FFFFFF; --ink:#1B2632; --muted:#736F63; --line:#DAD4C6;
  --brand:#2C3B4D; --brand-ink:#FFFFFF; --brand-soft:#E4E8EC;
  --good:#3F7A52; --good-bg:#E9F0E9;
  --warn:#8A5A1F; --warn-bg:#FCEFD9;
  --bad:#A35139;  --bad-bg:#F5E4DE;
  --accent:#FFB162; --accent-ink:#5A3406;
  --radius:12px; --radius-sm:9px; --gap:14px;
  --shadow:0 1px 2px rgba(27,38,50,.04);
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
/* Dark, for an account that has not chosen: follow the phone. */
@media (prefers-color-scheme:dark){
  :root[data-theme=auto]{
    --bg:#1B2632; --panel:#22303E; --ink:#EEE9DF; --muted:#9AA6AC; --line:#33424F;
    --brand:#FFB162; --brand-ink:#1B2632; --brand-soft:#3A2F22;
    --good:#6BCF98; --good-bg:#16281E;
    --warn:#FFB162; --warn-bg:#2A2216;
    --bad:#D97A5C;  --bad-bg:#2B1A1A;
    --accent:#FFB162; --accent-ink:#3A2F22;
    --shadow:0 1px 2px rgba(0,0,0,.25);
    color-scheme:dark;
  }
}
/* Dark, chosen. Outside the media query on purpose: a person who picks dark gets
   dark on a phone set to light, and a person who picks light (the default :root
   block above) keeps the cream design on a phone set to dark. */
:root[data-theme=dark]{
  --bg:#1B2632; --panel:#22303E; --ink:#EEE9DF; --muted:#9AA6AC; --line:#33424F;
  --brand:#FFB162; --brand-ink:#1B2632; --brand-soft:#3A2F22;
  --good:#6BCF98; --good-bg:#16281E;
  --warn:#FFB162; --warn-bg:#2A2216;
  --bad:#D97A5C;  --bad-bg:#2B1A1A;
  --accent:#FFB162; --accent-ink:#3A2F22;
  --shadow:0 1px 2px rgba(0,0,0,.25);
  color-scheme:dark;
}
:root[data-theme=light]{color-scheme:light}

*{box-sizing:border-box}
html,body{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg); color:var(--ink);
  font:16px/1.5 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  overflow-wrap:break-word;
  /* the header and nav are sticky, so anchor jumps must clear them */
  scroll-padding-top:104px;
}
/* Arabic. No web font: system-ui resolves to a real Arabic face on every phone
   his father might hold, and a downloaded font on a mediocre connection is the
   opposite of what this product is for. Two corrections the Latin design needs:
   Arabic sits taller in its line, and letter-spacing - which the design uses on
   small uppercase labels - has no meaning in a joined script and only pulls the
   letterforms apart. */
html[lang=ar] body{
  font-family:system-ui,-apple-system,"Segoe UI","Noto Sans Arabic","Geeza Pro",Tahoma,Arial,sans-serif;
  line-height:1.65;
}
html[lang=ar] .stat-l,html[lang=ar] th,html[lang=ar] .brand{letter-spacing:normal; text-transform:none}
/* A money figure, a date or an account reference is a Latin-digit run inside an
   Arabic sentence. Isolating it stops the bidi algorithm pulling a neighbouring
   word into the middle of it. */
.amt,.stat-v,.q-amt,.mono,td.num,.chip{unicode-bidi:isolate}

/* every page is a full document load; this makes the swap a cross-fade instead
   of a white flash, in the browsers that support it, and costs nothing elsewhere */
@view-transition{navigation:auto}
/* no 300ms tap delay, no grey flash on tap */
a,button,input,select,textarea,label,summary{touch-action:manipulation}
a,button{-webkit-tap-highlight-color:transparent}
a{color:var(--brand); text-decoration:none}
:focus-visible{outline:2px solid var(--brand); outline-offset:2px; border-radius:4px}
@media (hover:hover){ a:hover{text-decoration:underline} }

h1{font-size:1.35rem; line-height:1.25; margin:0 0 2px; font-weight:700}
h2{font-size:1.02rem; margin:0; font-weight:650}
h3{font-size:.92rem; margin:0 0 6px; font-weight:600}
.sub{color:var(--muted); font-size:.86rem; margin:0 0 16px}
.muted{color:var(--muted)}
.small{font-size:.82rem}
.mono{font-family:var(--mono)}
.right{margin-inline-start:auto}

/* header + nav */
.top{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 16px; background:var(--brand); color:var(--brand-ink);
  padding-top:calc(10px + env(safe-area-inset-top));
  padding-left:calc(16px + env(safe-area-inset-left));
  padding-right:calc(16px + env(safe-area-inset-right));
  position:sticky; top:0; z-index:5;
}
.brand{display:flex; align-items:center; gap:9px; color:var(--brand-ink); font-weight:650; letter-spacing:.01em}
.brand:hover{text-decoration:none}
.mark{
  display:grid; place-items:center; width:28px; height:28px; border-radius:7px; flex-shrink:0;
  background:rgba(255,255,255,.18); color:var(--brand-ink);
  font-size:.72rem; letter-spacing:.04em; font-weight:700;
}
@media (prefers-color-scheme:dark){ :root[data-theme=auto] .mark{background:rgba(27,38,50,.16)} }
:root[data-theme=dark] .mark{background:rgba(27,38,50,.16)}
.signout{color:var(--brand-ink); opacity:.85; font-size:.85rem; padding:4px 2px}

.nav{
  display:flex; gap:2px; overflow-x:auto; background:var(--panel);
  border-bottom:1px solid var(--line); padding:0 8px; scrollbar-width:none;
  position:sticky; z-index:4; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  /* sits directly under the sticky header, notch included */
  top:calc(48px + env(safe-area-inset-top));
}
.nav-a{scroll-snap-align:center}
/* a tapped tab goes active immediately, before the next page has painted */
.nav-a.going{color:var(--brand); border-bottom-color:var(--brand); font-weight:600}
.nav::-webkit-scrollbar{display:none}
.nav-a{
  padding:11px 12px; font-size:.9rem; color:var(--muted); white-space:nowrap;
  border-bottom:2px solid transparent; min-height:44px; display:flex; align-items:center;
}
@media (hover:hover){ .nav-a:hover{text-decoration:none; color:var(--ink)} }
.nav-a.on{color:var(--brand); border-bottom-color:var(--brand); font-weight:600}

.wrap{
  max-width:760px; margin:0 auto;
  padding:16px 16px calc(40px + env(safe-area-inset-bottom));
  padding-left:calc(16px + env(safe-area-inset-left));
  padding-right:calc(16px + env(safe-area-inset-right));
}

.flash{padding:10px 16px; font-size:.9rem; background:var(--good-bg); color:var(--good)}
.flash.err{background:var(--bad-bg); color:var(--bad)}
.flash.warn{background:var(--warn-bg); color:var(--warn)}

/* cards */
.card{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:14px; margin:0 0 var(--gap); box-shadow:var(--shadow);
}
.card-h{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:10px; min-height:32px}
.card-h h2{min-width:0}
.card-h .btn{flex:0 0 auto; white-space:nowrap}
.card-h .btn.sm.ghost{border:0; background:none; padding:4px 0; font-weight:600; min-height:0}
.card-h .btn.sm.ghost::after{content:" \203A"; font-weight:400}
@media (hover:hover){ .card-h .btn.sm.ghost:hover{text-decoration:underline; opacity:1} }
.empty{color:var(--muted); font-size:.9rem; margin:6px 0}
.empty-state{
  padding:40px 16px; text-align:center; color:var(--muted);
  border:1px dashed var(--line); border-radius:var(--radius);
}
.empty-state .empty-t{font-weight:600; color:var(--ink); margin-bottom:4px}

/* the dashboard column set — one, two, then three columns */
.dashboard-cards{display:grid; grid-template-columns:1fr; gap:var(--gap); align-items:start}
/* min-width:0 is load-bearing. A grid item's default min-width is auto, so a track sized
   1fr still refuses to go below its content's minimum: at 320px the longest tenant name
   pushed all three cards to 316px inside a 288px column and the whole page scrolled
   sideways. The rows already truncate (.row-m is min-width:0, .row-t ellipses), but they
   never got the chance. Nothing else on the page needs this because nothing else puts an
   unbreakable line inside a grid track. */
.dashboard-cards>.card{margin-bottom:0; min-width:0}
/* A fourth card in a three-column grid would sit alone in the first column with two empty
   ones beside it. Latest activity spans instead: its content is sentences, which read
   better across the width than down a narrow column. Only from two columns up — on a
   phone every card is already full width. */
.dashboard-cards>.card.wide{grid-column:1 / -1}

/* stats */
.stats{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:var(--gap)}
.stat{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:12px; box-shadow:var(--shadow);
}
.stat-l{font-size:.74rem; text-transform:uppercase; letter-spacing:.05em; color:var(--muted)}
/* a money figure must never break across lines — at 320px "6,540.500" was
   splitting after the "5". It scales down instead. */
.stat-v{
  font-size:clamp(1.05rem, 5.6vw, 1.28rem); font-weight:680; margin-top:4px;
  font-variant-numeric:tabular-nums; white-space:nowrap; letter-spacing:-.01em;
}
.stat-s{font-size:.78rem; color:var(--muted); margin-top:2px}
.stat.bad .stat-v{color:var(--bad)}
.stat.good .stat-v{color:var(--good)}
.stat.warn .stat-v{color:var(--warn)}
.stat.mute .stat-v{color:var(--muted)}

/* chips */
.chip{
  display:inline-block; padding:2px 8px; border-radius:999px; font-size:.72rem; font-weight:600;
  background:var(--brand-soft); color:var(--brand); white-space:nowrap;
}
.chip.good{background:var(--good-bg); color:var(--good)}
.chip.warn{background:var(--warn-bg); color:var(--warn)}
.chip.bad{background:var(--bad-bg); color:var(--bad)}
.chip.mute{background:var(--line); color:var(--muted)}
a.chip:hover{text-decoration:none; filter:brightness(.97)}
.chips{display:flex; flex-wrap:wrap; gap:5px}

/* The attribute chips on the reminder editor. A button, not a span: it is tapped on a
   phone and dragged on a desktop, and only a button is reachable from a keyboard. */
.chip-btn{
  display:inline-block; padding:6px 11px; border-radius:999px; font-size:.78rem;
  font-weight:600; background:var(--brand-soft); color:var(--brand);
  border:1px solid transparent; cursor:grab; white-space:nowrap; min-height:32px;
  font-family:inherit;
}
.chip-btn:hover{border-color:var(--brand)}
.chip-btn:active{cursor:grabbing; transform:translateY(1px)}

/* The message as the tenant will read it. The placeholders are filled in and marked, so
   he can see at a glance which words are his and which the app supplies. */
.preview-msg{
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:12px 14px; min-height:64px; line-height:1.6; white-space:pre-wrap;
  overflow-wrap:anywhere; font-size:.92rem;
}
.preview-msg .pill{
  display:inline; padding:1px 6px; border-radius:6px; font-weight:600;
  background:var(--brand-soft); color:var(--brand);
}
.preview-msg .pill.bad{background:var(--bad-bg); color:var(--bad)}
.preview-empty{color:var(--muted)}

/* A checkbox with its label on one line, used by the buildings list and the editor.
   NOT .pick - that name was already taken by the decision blocks on /review. */
.checkline{display:flex; align-items:center; gap:9px; min-height:44px; cursor:pointer}
.checkline input{width:18px; height:18px; flex:none; margin:0}

/* lists */
.rows{list-style:none; margin:0; padding:0}
/* 98 units and five years of rows: rendering only what is on screen keeps
   scrolling smooth on an old phone. contain-intrinsic-size stops the
   scrollbar jumping as rows come into view. */
.rows>li,.q-row{content-visibility:auto; contain-intrinsic-size:auto 56px}
.row{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 2px; border-bottom:1px solid var(--line); min-height:44px;
}
.row:last-child{border-bottom:0}
.row-m{min-width:0; flex:1}
.row-t{font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* A row list is normally a list of records - a tenant, a unit, a month - and a record's
   title is a name that must stay on one line and ellipse rather than wrap. But the same
   row markup is also used for explanations, where a title is a sentence and truncating it
   loses the point ("Where the sheet restarts a balance…" cut off at 390px). .prose says
   this list is prose: everything in it wraps. */
.rows.prose .row-t{white-space:normal; overflow:visible; text-overflow:clip}
.rows.prose .row-s{white-space:normal}
/* a row title is a heading first and a link second — brand-coloured names turn a
   list into a wall of colour, worst of all in dark mode where brand is amber */
.row-t a,.q-main .row-t a,td a{color:inherit}
@media (hover:hover){ .row-t a:hover,.q-main .row-t a:hover,td a:hover{text-decoration:underline} }
.row-s{font-size:.8rem; color:var(--muted); margin-top:1px}
/* the rent roll on a property row (session 13). The figure is the point of the line,
   so it takes the ink colour while the "+ x from n empty" tail stays muted. isolate for
   the same reason .amt does: a Western-digit amount inside an Arabic sentence must not
   be re-ordered by the bidi algorithm. */
.row-s.rent{color:var(--ink); font-variant-numeric:tabular-nums; unicode-bidi:isolate; margin-top:3px}
.row-s.rent .free{color:var(--muted); font-weight:400}
.row-r{
  display:flex; flex-direction:column; align-items:flex-end; gap:2px;
  text-align:end; white-space:nowrap; font-variant-numeric:tabular-nums;
}
.row-r .amt{font-weight:650; white-space:nowrap}
.amt.bad{color:var(--bad)} .amt.good{color:var(--good)} .amt.warn{color:var(--warn)} .amt.mute{color:var(--muted)}

/* the statement table */
.scroll{
  overflow-x:auto; -webkit-overflow-scrolling:touch;
  margin:0 -14px; padding:0 14px; border-radius:8px;
  /* the right-edge shadow is the only signal that money columns continue
     off-screen; it fades out on its own once the table is scrolled to the end */
  background:
    linear-gradient(to left, var(--panel) 40%, rgba(255,255,255,0)) right center / 26px 100% no-repeat local,
    radial-gradient(farthest-side at 100% 50%, rgba(27,38,50,.16), rgba(27,38,50,0)) right center / 11px 100% no-repeat scroll;
}
.scroll-hint{font-size:.78rem; color:var(--muted); margin:8px 0 0}
table{border-collapse:collapse; width:100%; font-size:.85rem; min-width:620px}
th,td{padding:8px 9px; text-align:end; white-space:nowrap; border-bottom:1px solid var(--line)}
th{
  font-size:.7rem; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); font-weight:600;
  position:sticky; top:0; z-index:1; background:var(--panel);
}
th:first-child,td:first-child{text-align:start; font-weight:600}
th:first-child{z-index:2}
td:first-child{position:sticky; inset-inline-start:0; background:var(--panel); box-shadow:1px 0 0 var(--line)}
th:first-child{box-shadow:1px 0 0 var(--line)}
td.num{font-variant-numeric:tabular-nums}
tr.paid td{color:var(--muted)}
tfoot td{font-weight:700; border-top:2px solid var(--line); border-bottom:0; background:var(--panel)}

/* the note that explains a per-row status against a running balance */
.note{
  font-size:.82rem; color:var(--muted); background:var(--brand-soft);
  border-radius:10px; padding:12px 14px; margin:12px 0 0;
}

/* forms */
label{display:block; font-size:.82rem; color:var(--muted); margin:12px 0 5px; font-weight:600}
/* The file control on /import was the one raw browser widget left in the product, sitting
   under a styled label on a styled card. The button inside it is a shadow part, so it has
   to be reached separately - and it is the thing a person actually taps, so it gets the
   ghost button's shape and the 44px target the rest of the UI uses. */
input[type=file]{
  display:block; width:100%; font:inherit; color:var(--ink); background:var(--panel);
  border:1px solid var(--line); border-radius:var(--radius-sm); padding:8px 10px;
}
input[type=file]::file-selector-button{
  font:inherit; font-weight:600; color:var(--ink); background:transparent;
  border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:8px 12px; margin-inline-end:12px; min-height:36px; cursor:pointer;
  touch-action:manipulation;
}
@media (hover:hover){ input[type=file]::file-selector-button:hover{ background:var(--brand-soft) } }
input[type=file]:focus-visible{ outline:2px solid var(--brand); outline-offset:2px }
input,select,textarea{
  width:100%; padding:11px 12px; font:inherit; color:var(--ink);
  background:var(--bg); border:1px solid var(--line); border-radius:var(--radius-sm);
}
/* The open list of a <select> is drawn by the OS: give it a SOLID background and the theme ink,
   or Windows Chrome falls back to white behind light text (session 16). */
select option,select optgroup{background-color:var(--panel); color:var(--ink)}
input:focus,select:focus,textarea:focus{outline:2px solid var(--brand); outline-offset:1px; border-color:var(--brand)}
input.err,select.err,textarea.err{border-color:var(--bad)}
input[type=checkbox]{width:20px; height:20px; accent-color:var(--brand)}
.field-h{font-size:.78rem; color:var(--muted); margin-top:5px}
.field-e{font-size:.78rem; color:var(--bad); margin-top:5px}
.grid2{display:grid; gap:0; grid-template-columns:1fr}

/* --- the searchable picker and the date box (session 13) -------------------------
   Both wrap a native control that is still in the form and still what gets submitted.
   .combo-native and .date-native are therefore positioned over the field at zero
   opacity rather than hidden: a `required` control the browser cannot focus makes
   Chrome refuse the submit with no visible reason. pointer-events:none so every tap
   reaches the box in front. */
.combo,.datef{position:relative}
.combo-native,.date-native{
  position:absolute; inset:0; width:100%; height:100%; min-height:0;
  opacity:0; pointer-events:none; border:0; padding:0; margin:0;
}
.combo-in{padding-inline-end:34px}
/* the chevron, drawn rather than fetched - one less asset and it follows the ink */
.combo::after{
  content:''; position:absolute; inset-inline-end:13px; top:50%; width:7px; height:7px;
  margin-top:-5px; border-inline-end:2px solid var(--muted); border-block-end:2px solid var(--muted);
  transform:rotate(45deg); pointer-events:none;
}
.combo.open::after{margin-top:-2px; transform:rotate(225deg)}
.combo-list{
  position:absolute; z-index:40; inset-inline:0; top:calc(100% + 4px);
  margin:0; padding:4px; list-style:none; max-height:min(46vh, 320px); overflow-y:auto;
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius-sm);
  box-shadow:0 8px 24px rgba(27,38,50,.14);
  -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
}
:root[data-theme=dark] .combo-list{box-shadow:0 8px 24px rgba(0,0,0,.45)}
@media (prefers-color-scheme:dark){ :root[data-theme=auto] .combo-list{box-shadow:0 8px 24px rgba(0,0,0,.45)} }
.combo-opt{
  padding:10px 11px; border-radius:7px; cursor:pointer; font-size:.92rem;
  min-height:40px; display:flex; align-items:center;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.combo-opt.on{background:var(--brand-soft)}
.combo-opt[aria-selected=true]{font-weight:650}
@media (hover:hover){ .combo-opt:hover{background:var(--brand-soft)} }
.combo-none{padding:10px 11px; color:var(--muted); font-size:.88rem}

.date-in{padding-inline-end:44px}
.date-cal{
  position:absolute; inset-inline-end:4px; top:50%; transform:translateY(-50%);
  width:36px; height:36px; display:flex; align-items:center; justify-content:center;
  padding:0; border:0; background:transparent; color:var(--muted); cursor:pointer;
  border-radius:8px; touch-action:manipulation;
}
.date-cal svg{width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.5;
  stroke-linecap:round}
@media (hover:hover){ .date-cal:hover{background:var(--brand-soft); color:var(--ink)} }
.date-cal:focus-visible{outline:2px solid var(--brand); outline-offset:1px}
/* the one-interaction fallback for a browser without showPicker(): give its own box back */
.datef.show-native .date-in,.datef.show-native .date-cal{display:none}
.datef.show-native .date-native{
  position:static; opacity:1; pointer-events:auto; width:100%; min-height:44px;
  padding:11px 12px; border:1px solid var(--brand); border-radius:var(--radius-sm);
  background:var(--bg); color:var(--ink);
}

.btn{
  display:inline-block; padding:11px 16px; border-radius:var(--radius-sm);
  border:1px solid var(--brand); background:var(--brand); color:var(--brand-ink);
  font:inherit; font-size:.9rem; font-weight:640; cursor:pointer; text-align:center;
  min-height:44px; line-height:1.4;
}
@media (hover:hover){ .btn:hover{text-decoration:none; opacity:.92} }
.btn.ghost{background:transparent; color:var(--brand)}
.btn.danger{background:var(--bad); border-color:var(--bad); color:#fff; min-height:48px}
.btn.sm{padding:7px 11px; font-size:.85rem; min-height:0}
.btn.block{display:block; width:100%; margin-top:16px; min-height:48px}
.btn.wa{
  background:transparent; color:var(--good); border-color:var(--good);
  padding:6px 10px; border-radius:8px; font-size:.8rem; font-weight:600; min-height:0;
}
.btn:disabled{opacity:.5; cursor:not-allowed}
.actions{display:flex; gap:9px; flex-wrap:wrap; margin:16px 0}

/* login */
.login{max-width:404px; margin:12vh auto; padding:0 20px}
.login .card{padding:22px; max-width:364px; margin:0 auto}

/* arrears queue */
.q-row{display:flex; gap:11px; padding:12px 2px; border-bottom:1px solid var(--line); align-items:flex-start}
.q-row:last-child{border-bottom:0}
.q-main{flex:1; min-width:0}
.q-amt{text-align:end; font-variant-numeric:tabular-nums; font-weight:650; color:var(--bad); white-space:nowrap}

.bar{display:flex; gap:9px; align-items:center; flex-wrap:wrap; margin-bottom:12px}
.bar input[type=search]{flex:1; min-width:180px}

/* On a phone the bordered pill beside every card title is noise and steals the
   width the title needs. Below 560px the card's secondary action is a text link;
   above it, the outlined button returns. */
@media (max-width:559.98px){
  .actions>.btn:first-child{flex:1 1 100%; min-height:48px}
  .actions>.btn{flex:1 1 0; min-width:0}
}

/* ---------------------------------------------------------------- the ladder
   320 · 390 phone   |   720 tablet portrait   |   840 wide tablet   |   1080 desktop
   The mockup put its tablet band at 840, which left an iPad in portrait rendering
   as a very wide phone with a side-scrolling ledger. It starts at 720 here. */

/* The allocation table carries the input he types into. It must never be the
   thing that scrolls off-screen, so on a phone it drops the Due column (the
   period already says which month) and fits instead. */
table.alloc{min-width:0}
table.alloc input{min-width:88px; padding:9px 10px}
@media (max-width:559.98px){
  table.alloc th,table.alloc td{padding:8px 6px}
  table.alloc .col-due{display:none}
  /* the status chip drops under the month so the input keeps its width */
  table.alloc td:first-child{white-space:normal}
  table.alloc td:first-child .chip{display:inline-block; margin-top:3px}
}

/* ---- 560px: two fields per row ---- */
@media (min-width:560px){
  .grid2{grid-template-columns:1fr 1fr; gap:0 12px}
}

/* ---- 640px: the four stats go on one line ---- */
@media (min-width:640px){
  .stats{grid-template-columns:repeat(4,1fr)}
}

/* ---- 720px (tablet portrait) ---- */
@media (min-width:720px){
  .wrap.wide{max-width:1080px}
  .dashboard-cards{grid-template-columns:repeat(2,1fr)}
  th,td{padding:9px 11px}
}

/* ---- 900px: the ledger fits, so it stops scrolling ----
   This used to be 720. The statement gained a column - the day each payment
   actually arrived, which is how a row gets matched against a bank transfer -
   and seven columns no longer fit in 720. When they did not, the PAGE started
   scrolling sideways instead of the table, which is the one thing the layout is
   not allowed to do. The number is the ledger's own width, so it lives with the
   ledger's rules and not with the dashboard's. */
@media (min-width:900px){
  .scroll{overflow-x:visible; margin:0; padding:0; background:none}
  .scroll-hint{display:none}
  table{min-width:0}
  td:first-child{position:static; box-shadow:none}
  th:first-child{box-shadow:none}
}

/* ---- 840px: all five tabs fit, so the nav stops being a scroller ---- */
@media (min-width:840px){
  .nav{overflow-x:visible; padding:0 16px}
}

/* ---- 1080px (desktop): three columns, and the ledger gets its full width ---- */
@media (min-width:1080px){
  .wrap{max-width:1080px}
  .dashboard-cards{grid-template-columns:repeat(3,1fr)}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important}
}

/* ------------------------------------------------------------------ /review
   One question, three answers, each in its own bordered block so the buttons
   underneath can only be read as belonging to the answer above them. This markup
   has been on /review since it was built and the stylesheet had never been given
   it - the screen was rendering three unseparated walls of text. A screen nobody
   designed is exactly the one that drifts. */
.pick{
  border:1px solid var(--line); border-radius:var(--radius); background:var(--bg);
  padding:12px 14px; margin:0 0 12px;
}
.pick:last-child{margin-bottom:0}
.pick-t{font-weight:650; color:var(--ink); margin-bottom:2px}
.pick .field-h{margin-top:0}
.pick .actions{margin:12px 0 0}
.pick label{margin-top:10px}
/* the month the decision is about, inside the window of months around it */
tr.here td,tr.here td:first-child{background:var(--brand-soft); font-weight:650}

/* ------------------------------------------------------------- right to left
   Everything above is written in logical properties and flips on its own. These
   cannot: a box-shadow and a background-position are physical, and a chevron
   points the way the reader reads. */
[dir=rtl] td:first-child,[dir=rtl] th:first-child{box-shadow:-1px 0 0 var(--line)}
[dir=rtl] .scroll{
  background:
    linear-gradient(to right, var(--panel) 40%, rgba(255,255,255,0)) left center / 26px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(27,38,50,.16), rgba(27,38,50,0)) left center / 11px 100% no-repeat scroll;
}
[dir=rtl] .card-h .btn.sm.ghost::after{content:" \2039"}

/* MONEY IS NOT ARABIC TEXT, and the first Arabic render proved it twice.
   -30.000 came out as 30.000- : a minus sign is bidi-neutral, so in an RTL
   paragraph it is placed at what the paragraph calls the end. And in the ledger,
   0.000 and 480.000 both started at the left edge of their cell, so the decimal
   points no longer lined up - the one thing that makes five years of a running
   balance readable at a glance, and the reason his sheets are readable at all.
   So a figure is its own little left-to-right island, and in a table it ends
   where every other figure in that column ends. */
[dir=rtl] .amt,[dir=rtl] .stat-v,[dir=rtl] .q-amt,[dir=rtl] td.num,[dir=rtl] .mono{
  direction:ltr;
}
[dir=rtl] .stat-v,[dir=rtl] .q-amt{text-align:right}
[dir=rtl] th,[dir=rtl] td{text-align:right}
[dir=rtl] th:first-child,[dir=rtl] td:first-child{text-align:right}

/* ---- print: the statement gets handed to a tenant or an accountant ---- */

/* ------------------------------------------------------- the navigation progress line
   Shown only when a screen takes longer than 200ms to arrive, and never in place of the
   screen you are reading - the outgoing view stays until the incoming one is ready, so
   there is no white frame between two tabs. It sits directly under the sticky nav.

   It is a fixed-position line rather than anything in the flow, so it can appear and
   disappear without moving a single pixel of the page: the smoothness requirement is
   that a swap causes no layout shift, and an element that reserves no space cannot. */
.nav-bar{
  position:fixed; left:0; right:0; z-index:6;
  top:calc(48px + env(safe-area-inset-top));
  height:2px; background:var(--brand);
  /* transform-origin has no logical keywords - left/right is the only way to say this,
     so the RTL case is an explicit override rather than something the browser flips. */
  transform:scaleX(0); transform-origin:left center;
  opacity:0; pointer-events:none;
}
[dir=rtl] .nav-bar{transform-origin:right center}
.nav-bar.on{
  opacity:1;
  /* Runs to 90% and waits there. It cannot honestly claim to know how far along a
     response is, so it does not: it shows that something is happening and stops. */
  animation:nav-bar-grow 2.4s cubic-bezier(.15,.85,.35,1) forwards;
}
@keyframes nav-bar-grow{
  from{transform:scaleX(.05)}
  to{transform:scaleX(.9)}
}
/* The router moves focus to <main> so a screen reader and a keyboard land on the new
   screen. That must not draw a focus ring for someone who clicked. */
main:focus{outline:none}
main:focus-visible{outline:2px solid var(--brand); outline-offset:4px}

@media (prefers-reduced-motion:reduce){
  .nav-bar.on{animation:none; transform:scaleX(1)}
}

@media print{
  :root{
    --bg:#fff; --panel:#fff; --ink:#000; --muted:#444; --line:#999;
    --brand:#000; --brand-soft:#fff; --good:#000; --warn:#000; --bad:#000; --shadow:none;
  }
  .top,.nav,.nav-bar,.actions,.bar,.btn,.flash,.note,.signout{display:none !important}
  body{background:#fff; color:#000; font-size:11pt}
  .wrap,.wrap.wide{max-width:none; padding:0}
  .card{border:0; box-shadow:none; padding:0; margin:0 0 12pt}
  .scroll{overflow:visible; margin:0; padding:0}
  table{min-width:0; font-size:10pt; width:100%}
  th{position:static; background:#fff}
  .scroll-hint{display:none}
  td:first-child{position:static; background:#fff}
  th,td{border-bottom:1px solid #999}
  .stats{grid-template-columns:repeat(4,1fr)}
  .stat{border:1px solid #999; box-shadow:none}
  .chip{border:1px solid #999; background:#fff !important; color:#000 !important}
  thead{display:table-header-group}
  tr{break-inside:avoid}
  @page{size:A4; margin:14mm}
}


/* ---------------------------------------------------------------- rent, vacancies, archiving
   Added with the Rent and Empty units screens. Everything here is a variation on a shape
   the stylesheet already had, because a screen with classes nobody wrote is exactly the
   one that drifts - /review had .pick and .pick-t for a month with no rules behind them. */

/* Several small decisions on one row. On a phone they stack under the amount rather
   than squeezing the unit number to nothing. */
.pick-row{display:flex; flex-wrap:wrap; gap:6px; justify-content:flex-end; margin-top:6px}
.pick-row .btn{white-space:nowrap}
@media (max-width:520px){
  .row.wrapme{flex-wrap:wrap}
  .row.wrapme .row-r{width:100%; text-align:start; margin-top:6px}
  .row.wrapme .pick-row{justify-content:flex-start}
}

/* A filter chip that is a link, and the one that is currently on. */
a.chip.on{background:var(--brand); color:var(--panel); font-weight:600}
a.chip b{font-weight:700; margin-inline-start:4px}

/* The statement's new column: the day the money actually arrived. Narrow, quiet, and
   it must never push the balance off the table. */
.paid-on{color:var(--muted); white-space:nowrap; font-size:.8rem}

/* A figure inside a sentence. Money and dates are Latin-digit runs; in an Arabic
   paragraph the bidi algorithm otherwise puts "700.000 OMR" back as "OMR 700.000". */
.ltr{unicode-bidi:isolate}
[dir=rtl] .ltr{direction:ltr; display:inline-block}

/* A section heading between cards. */
h2.sec{font-size:1.05rem; margin:22px 0 6px}

/* The message to send about an empty unit. Pre, because the line breaks are the point. */
.offer{
  background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:10px 12px;
  white-space:pre-wrap; font-family:inherit; font-size:.9rem; line-height:1.5; margin:0 0 10px;
  overflow-wrap:anywhere;
}

/* A checkbox with its label beside it, not above it. */
label.check{
  display:flex; align-items:flex-start; gap:9px; font-weight:400; font-size:.9rem;
  margin:12px 0 4px; cursor:pointer; line-height:1.45;
}
label.check input{width:auto; min-height:0; margin:2px 0 0; flex:none}

/* A note that is a warning rather than a remark: archived, hidden, not billed. */
.note.warn{background:var(--warn-bg); color:var(--warn); border-color:transparent}

/* The occupancy figure is a way in to the empty units, so the whole tile is the target. */
a.stat-link{display:block; color:inherit}
a.stat-link:hover{text-decoration:none}
a.stat-link .stat{height:100%}

/* A day heading inside the log, so five years of rows read as days and not as a list. */
.log-day{background:var(--bg); border-bottom:1px solid var(--line)}
.log-day .row-t{font-size:.78rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color:var(--muted)}

/* When a log line happened. Small and quiet: the sentence is the content, the clock is a
   footnote — and it must not take width away from the sentence, which is what truncated
   "Abdulmalik Al Lamki added a payment" to the name alone on the first attempt. */
.log-when{font-size:.72rem; color:var(--muted); line-height:1.35; flex:none}

/* --- utilities (session 13) -------------------------------------------------------
   These replace the 58 inline style= attributes the CSP had been silently refusing in
   production since the nonce-only policy went in. style-src is 'nonce-…' with no
   unsafe-inline, and a style="…" ATTRIBUTE is exactly what that forbids — Chrome logged
   "Refused to apply inline style" for every one, and the worst of them, 229 forms on
   /billing carrying style="display:inline", meant each of those forms was a block on the
   screen his father opens every morning.

   They live at the END of the sheet on purpose: every one of them is replacing a
   declaration that used to win by being inline, so it has to win here by coming last.
   Where a component rule is more specific than a single class, the utility is written to
   match it rather than reaching for !important. Nothing above this line changed. */
.m0{margin:0}
.mt0{margin-top:0} .mt3{margin-top:3px} .mt4{margin-top:4px} .mt6{margin-top:6px}
.mt8{margin-top:8px} .mt10{margin-top:10px} .mt14{margin-top:14px}
.mb10{margin-bottom:10px} .mb12{margin-bottom:12px} .mb14{margin-bottom:14px}
.mb16{margin-bottom:16px} .mb18{margin-bottom:18px}
.ctr{text-align:center}
.r9{border-radius:9px}
.minw110{min-width:110px}
.maxw420{max-width:420px}
/* a row whose subtitle is a sentence, not a name: it wraps instead of ellipsing */
.txt-wrap{white-space:normal}
/* a row whose left column is taller than one line - the title should sit at the top of
   it rather than be centred against a three-line summary */
.ai-start{align-items:flex-start}
/* a form that is only there to carry one button, sitting in a row of buttons */
.inl{display:inline}
/* the tick-box label on the reminder rows: a label, but laid out as a line */
.label-inline{
  margin:0; display:flex; align-items:center; gap:8px; font-weight:600; color:var(--ink);
}
/* the AD mark at 44px on the sign-in and first-run screens. :root … beats the two
   data-theme rules that repaint .mark in dark mode. */
.mark.mark-lg{margin:0 auto 10px; width:44px; height:44px; font-size:1rem}
:root .mark.mark-lg{background:var(--brand); color:#fff}

/* ------------------------------------------------------------------- charts (session 14)
   The palette was CHECKED, not chosen. Charged against collected is one hue at two
   lightnesses rather than green against red: that pair separates at ΔE 4.3 under
   deuteranopia on the light theme - which is to say it does not separate at all - while
   two steps of the brand hue separate at ΔE 44 for every kind of colour vision. The pale
   step sits below 3:1 against the surface, so every figure it carries is also written out
   beside the chart and again in the table further down the page.
   Arrears ageing is one colour and four positions. Four steps of a single hue could not
   hold ΔE 15 between neighbours, and age is already ordered, so position carries it. */
:root{
  --ch-ink:#2C3B4D; --ch-pale:#AFBBC7; --ch-bad:#A35139;
  --ch-grid:#E7E2D6; --ch-axis:#736F63;
}
@media (prefers-color-scheme:dark){
  :root[data-theme=auto]{
    --ch-ink:#FFB162; --ch-pale:#7A6446; --ch-bad:#D97A5C;
    --ch-grid:#33424F; --ch-axis:#9AA6AC;
  }
}
:root[data-theme=dark]{
  --ch-ink:#FFB162; --ch-pale:#7A6446; --ch-bad:#D97A5C;
  --ch-grid:#33424F; --ch-axis:#9AA6AC;
}

.ch-wrap{margin:4px 0 0}
/* width:100% so it shrinks on a phone, max-width so it never GROWS past the size its
   type was drawn at: the viewBox is 680 wide, and stretching that to a 1,070px card
   scaled every 11px axis label to 17px and made the value labels shout. */
.ch{display:block; width:100%; max-width:680px; height:auto; overflow:visible}
.ch-ink{fill:var(--ch-ink)}
.ch-pale{fill:var(--ch-pale)}
.ch-bad{fill:var(--ch-bad)}
.ch-grid{stroke:var(--ch-grid); stroke-width:1}
.ch-base{stroke:var(--line); stroke-width:1}
.ch-area{fill:var(--ch-ink); opacity:.13}
.ch-line{fill:none; stroke:var(--ch-ink); stroke-width:2; stroke-linejoin:round; stroke-linecap:round}
/* a 2px surface ring, so a dot sitting on the line still reads as a separate mark */
.ch-dot{fill:var(--ch-ink); stroke:var(--panel); stroke-width:2}
.ch-axis{fill:var(--ch-axis); font-size:11px; font-weight:600}
.ch-axis.dim{font-size:10px; font-weight:400; opacity:.75}
/* a value written on the mark wears a text token, never the series colour */
.ch-val{fill:var(--ink); font-size:11px; font-weight:650; font-variant-numeric:tabular-nums}
html[lang=ar] .ch-axis,html[lang=ar] .ch-val{letter-spacing:normal}

/* the key under the charged/collected chart. Two series, so it is always present. */
.ch-key{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 14px;
  font-size:.78rem; color:var(--muted); margin:8px 0 0;
}
.ch-sw{display:inline-block; width:11px; height:11px; border-radius:3px; margin-inline-end:5px;
  vertical-align:-1px}
.ch-sw.ink{background:var(--ch-ink)}
.ch-sw.pale{background:var(--ch-pale)}

/* the fill bar beside a building's let count in the table */
.ch-mini{display:inline-block; width:46px; height:8px; vertical-align:middle;
  margin-inline-start:7px}

/* What stands out. Sentences, so they wrap and they are not a list of records. */
.card.obs .row{align-items:flex-start}
.card.obs .row-t{font-weight:500; white-space:normal; line-height:1.55}

/* the dashboard's analytics panel — three figures and a sentence, no chart. It sits
   BELOW the arrears queue on a phone for a reason: the queue is the work, this is the
   weather. */
.an-panel{display:flex; flex-wrap:wrap; gap:18px 26px; margin:0 0 10px}
.an-f{min-width:92px}
.an-f .stat-l{font-size:.72rem}
.an-f .stat-v{font-size:1.12rem; font-weight:680; margin-top:2px;
  font-variant-numeric:tabular-nums; white-space:nowrap}
.an-note{font-size:.88rem; color:var(--ink); margin:0; line-height:1.55}

/* ---------------------------------------------------------------- expenses (session 15)
   The category is one tap: every choice is a tile, grouped Bills / Repairs / Other.
   A real radio underneath, so it is submitted, required and keyboard-reachable exactly
   like a native control, and works with JavaScript off. */
fieldset.cat-group{border:0; margin:0 0 12px; padding:0; min-width:0}
fieldset.cat-group:last-child{margin-bottom:0}
fieldset.cat-group legend{font-size:.82rem; color:var(--muted); font-weight:600; padding:0; margin:4px 0 7px}
.cat-grid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px}
label.cat{
  position:relative; display:flex; align-items:center; justify-content:center; text-align:center;
  min-height:48px; margin:0; padding:8px 10px; border:1.5px solid var(--line); border-radius:var(--radius-sm);
  background:var(--panel); color:var(--ink); font-size:.95rem; font-weight:600; cursor:pointer;
}
label.cat input{position:absolute; opacity:0; width:1px; height:1px; min-height:0; margin:0; pointer-events:none}
label.cat:has(input:checked){border-color:var(--brand); background:var(--brand-soft); box-shadow:inset 0 0 0 1px var(--brand)}
label.cat:has(input:focus-visible){outline:2px solid var(--brand); outline-offset:2px}
/* Older WebViews without :has() still show which one is chosen - app.js adds .on */
label.cat.on{border-color:var(--brand); background:var(--brand-soft); box-shadow:inset 0 0 0 1px var(--brand)}
@media (min-width:560px){ .cat-grid{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:840px){ .cat-grid{grid-template-columns:repeat(5,minmax(0,1fr))} }

/* a voided expense stays in the list, struck and quiet */
.row.voided .row-t,.row.voided .amt{text-decoration:line-through; color:var(--muted)}

.dash-cost{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin:0 0 6px}
.dash-cost .amt{font-size:1.35rem; font-weight:700; font-variant-numeric:tabular-nums}
td.num.bad{color:var(--bad)}
.month-nav .btn:last-child{margin-inline-start:auto}

/* ------------------------------------------------------------------- the logo (2026-09-25)
   src/lib/logo.js. Letters are currentColor; the door and its knob are classed so a
   header whose ground is amber (Classic dark) can turn the door into a dark shape with
   an amber knob instead of an amber door on an amber bar. The Classic header shows the
   wordmark alone: its first A already carries the door, so the square mark would say it twice. */
.lg-door{fill:var(--lg-door,#FFB162)}
.lg-knob{fill:var(--lg-knob,#2C3B4D)}
.logo-w{display:block; height:17px; width:auto; overflow:visible}
.logo-w.ar{height:24px; transform:translateY(1px)}
.logo-i{display:block; width:58%; height:58%}
.top .brand .mark{display:none}
@media (prefers-color-scheme:dark){ :root[data-theme=auto] .top{--lg-door:currentColor; --lg-knob:var(--brand)} }
:root[data-theme=dark] .top{--lg-door:currentColor; --lg-knob:var(--brand)}
.logo-h{display:flex; justify-content:center; margin:0 0 12px; color:var(--ink)}
.logo-h .logo-w{height:34px}
.logo-h .logo-w.ar{height:48px}

/* ------------------------------------------------------- restore progress (/backup)
   Abdul, drill 1: a bar and one line, not a running list. The full list is still kept,
   folded under "Show details", for the day something goes wrong. */
.restore-status{margin-top:12px}
.restore-bar{display:block; width:100%; height:10px; accent-color:var(--brand)}
.restore-line{margin:8px 0 0}
.restore-more{margin-top:8px}
.restore-more pre{white-space:pre-wrap; margin:6px 0 0}


/* ---------------------------------------------------------------- Phase 3: the account's own brand
   (docs/PRD-PHASE3.md §5). Only a branded account renders any of these classes, so an account
   without a logo - account #1 - draws exactly what it drew before. */
.top .brand .mark.brand-own,.mark.brand-own{display:grid; width:36px; height:36px; border-radius:8px; overflow:hidden; background:#fff; padding:2px}
.brand-img{display:block; width:100%; height:100%; object-fit:contain}
.brand-name{font-size:1rem; font-weight:700; line-height:1.15; max-width:60vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.powered{margin:28px 0 8px; text-align:center; color:var(--muted); opacity:.8}
.print-brand{display:none}
.logo-preview{display:block; width:96px; height:96px; object-fit:contain; border:1px solid var(--line); border-radius:12px; background:#fff; padding:6px; margin:6px 0 10px}
.onb-steps{list-style:none; padding:0; margin:0}
.onb-step{display:flex; flex-wrap:wrap; gap:8px 10px; align-items:center; padding:10px 0; border-bottom:1px solid var(--line)}
.onb-step:last-child{border-bottom:0}
.onb-n{flex:0 0 26px; height:26px; border-radius:50%; display:grid; place-items:center; font-weight:700; font-size:.8rem; background:var(--brand-soft); color:var(--ink)}
.onb-step.done .onb-n{background:var(--good); color:#fff}
.onb-step.done .onb-t{text-decoration:line-through; color:var(--muted)}
.onb-m{flex:1 1 150px; min-width:0}
.onb-a{display:flex; flex-wrap:wrap; gap:6px; margin-inline-start:auto}
.onb-t{font-weight:650}
@media print{
  .powered{display:none}
  .print-brand{display:flex !important; align-items:center; gap:12pt; margin:0 0 12pt}
  .print-logo{width:48pt; height:48pt; object-fit:contain}
  .print-name{font-size:14pt; font-weight:700}
  .print-pow{font-size:8pt; color:#444}
}

/* Phase 3: the import grid (docs/PRD-PHASE3.md §7). */
.imp-grid{min-width:1100px}
.imp-grid input.imp-in{min-width:90px; padding:6px 8px; margin:0}
.imp-grid input.imp-wide{min-width:160px}
.imp-grid .imp-st{min-width:220px; font-size:.85rem}
.imp-grid tr.imp-ok .imp-st{color:var(--good)}
.imp-grid tr.imp-check .imp-st{color:var(--warn)}
.imp-grid tr.imp-error .imp-st{color:var(--bad)}
.imp-grid tr.imp-error td{background:var(--brand-soft)}

/* ---- Business identity (PRD-PHASE3 §12, 28/09): the logo editor, like a profile photo ---- */
.biz-id{display:flex; flex-direction:column; align-items:center; text-align:center; gap:6px; padding:22px 16px 18px;
  margin:6px 0 16px; background:var(--panel); border:1px solid var(--line); border-radius:22px}
.biz-av{width:112px; height:112px; border-radius:28px; overflow:hidden; display:grid; place-items:center;
  background:#fff; border:1px solid var(--line); box-shadow:0 8px 24px rgba(27,38,50,.12)}
.biz-av .brand-img{width:100%; height:100%; object-fit:contain}
.biz-av-aldar{display:grid; place-items:center; width:72px; height:72px; color:var(--brand)}
.biz-av-aldar svg{width:100%; height:100%}
.biz-id-n{font-size:1.25rem; font-weight:800; margin-top:6px; overflow-wrap:anywhere}
.biz-id-s{font-size:.86rem; color:var(--muted)}
/* A fold-out inside a card: a plain link-like line, content below it at full width. */
.g-fold{display:block; margin-top:8px}
.g-fold > summary{display:inline-flex; align-items:center; gap:6px; list-style:none; cursor:pointer;
  font-size:.86rem; font-weight:700; color:var(--brand); padding:4px 0}
.g-fold > summary::-webkit-details-marker{display:none}
.g-fold > summary::after{content:"\25BE"; font-size:.8em; transition:transform 150ms ease}
.g-fold[open] > summary::after{transform:rotate(180deg)}
.g-fold[open] > summary{margin-bottom:6px}
.biz-more{position:relative; margin-top:8px}
.biz-more > summary{list-style:none; cursor:pointer}
.biz-more > summary::-webkit-details-marker{display:none}
.biz-sheet{display:grid; gap:4px; margin-top:10px; min-width:min(320px, 86vw); padding:8px; text-align:start;
  background:var(--panel); border:1px solid var(--line); border-radius:20px; box-shadow:0 16px 40px rgba(27,38,50,.18)}
.biz-use{display:grid; gap:4px; padding:4px 4px 8px; border-bottom:1px solid var(--line)}
.biz-use-t{font-size:.78rem; font-weight:700; color:var(--muted); padding:4px 8px 2px}
.biz-opt{display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:14px; cursor:pointer; margin:0}
.biz-opt:hover{background:var(--brand-soft)}
.biz-opt small{color:var(--muted); margin-inline-start:auto}
.biz-opt.off{opacity:.55; cursor:default}
.biz-opt input{width:18px; height:18px; margin:0; accent-color:var(--brand)}
.biz-act{display:block; width:100%; padding:12px; border:0; border-radius:14px; background:none; color:var(--ink);
  font:inherit; font-weight:700; text-align:start; cursor:pointer; margin:0}
.biz-act:hover{background:var(--brand-soft)}
.biz-act.danger{color:#B3261E}
.biz-up{display:grid; gap:6px}
.biz-up-err{color:#B3261E; font-size:.86rem; margin:0 12px}
.biz-js .biz-nojs{display:none}
.biz-js .biz-file{position:absolute; width:1px; height:1px; opacity:0; pointer-events:none}
.biz-crop{width:min(460px, calc(100vw - 24px)); max-height:calc(100dvh - 24px); overflow:auto; padding:18px;
  border:1px solid var(--line); border-radius:24px; background:var(--panel); color:var(--ink)}
.biz-crop::backdrop{background:rgba(15,22,30,.55); backdrop-filter:blur(4px)}
.biz-crop h2{margin:0 0 12px; font-size:1.1rem}
.biz-stage{position:relative; border-radius:18px; overflow:hidden; background:
  repeating-conic-gradient(#e9e4da 0 25%, #fff 0 50%) 0 0/20px 20px}
.biz-stage canvas{display:block; width:100%; height:auto; aspect-ratio:1; touch-action:none; cursor:grab}
.biz-stage canvas:active{cursor:grabbing}
.biz-stage::after{content:""; position:absolute; inset:0; border-radius:18px; box-shadow:inset 0 0 0 2px rgba(255,255,255,.85); pointer-events:none}
.biz-zoom{display:flex; align-items:center; gap:12px; margin:14px 2px 6px; font-weight:700}
.biz-zoom input{flex:1; accent-color:var(--brand)}
.biz-prev{display:flex; gap:10px; flex-wrap:wrap; margin:10px 0}
.biz-prev > div{display:flex; align-items:center; gap:10px; padding:8px 12px; border:1px solid var(--line); border-radius:16px; flex:1; min-width:0}
.biz-pc{width:44px; height:44px; border-radius:12px; background:#fff; border:1px solid var(--line); flex:none}
.biz-prev-phone .biz-pc{width:30px; height:30px; border-radius:9px}
.biz-prev span{display:flex; flex-direction:column; min-width:0}
.biz-prev b{white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.biz-prev small{color:var(--muted); font-size:.72rem}
.biz-crop-err{color:#B3261E; font-weight:600}
.biz-names .btn:disabled{opacity:.45; cursor:default}
/* the sidebar brand, bigger, with the "powered by" line under the name */
.brand-big{width:44px !important; height:44px !important; border-radius:12px !important; flex:none}
.brand-stack{display:flex; flex-direction:column; min-width:0; line-height:1.15}
.brand-pow{font-size:.68rem; font-weight:600; color:var(--muted); letter-spacing:.02em}
.g-head-brand{display:flex; align-items:center; gap:14px}
.g-head-logo{display:block; width:56px; height:56px; flex:none; border-radius:16px; overflow:hidden; background:#fff;
  border:1px solid var(--line); box-shadow:0 6px 18px rgba(27,38,50,.10)}
.g-head-logo .brand-img{width:100%; height:100%; object-fit:contain}
.g-head-t{min-width:0}
.g-head-biz{color:var(--ink)}
.g-when-brand{display:flex; align-items:center; gap:10px; min-width:0; color:inherit}
.g-when-brand:hover{text-decoration:none}
.g-when-t{display:flex; flex-direction:column; min-width:0; line-height:1.15}
.g-when-n{font-weight:800; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.g-when-t .g-date{font-size:.72rem}
@media (prefers-color-scheme:dark){ :root[data-theme=auto] .biz-act.danger,:root[data-theme=auto] .biz-up-err,:root[data-theme=auto] .biz-crop-err{color:#FF8A80} }
:root[data-theme=dark] :is(.biz-act.danger,.biz-up-err,.biz-crop-err){color:#FF8A80}
.biz-zoom input[type=range]{border:0; background:none; box-shadow:none; padding:0; min-height:0; height:28px; border-radius:0}
.biz-prev > div{flex:1 1 190px}

/* Turnstile on sign-up / reset (29/09): full width like the fields, rounded, no square frame */
/* Turnstile at its own fixed size: no stretching, no clipping, no rounded crop (29/09) */
.ts-box{display:flex; justify-content:center; min-height:65px; margin:16px 0 6px; line-height:0}

/* ---- Import with the Aldar template only (29/09) ---- */
.imp-step{display:flex; gap:16px; align-items:flex-start}
.imp-n{flex:none; width:34px; height:34px; border-radius:50%; display:grid; place-items:center; font-weight:800;
  background:var(--brand); color:var(--brand-ink)}
.imp-b{flex:1; min-width:0}
.imp-b h2{margin:4px 0 8px; font-size:1.08rem}
.imp-tips{margin:0; padding-inline-start:20px; line-height:1.7}
.imp-drop{display:flex; align-items:center; justify-content:center; min-height:92px; margin:10px 0 4px; padding:16px;
  border:2px dashed var(--line); border-radius:18px; cursor:pointer; text-align:center; font-weight:700; color:var(--brand)}
.imp-drop:hover,.imp-drop:focus-within{border-color:var(--brand); background:var(--brand-soft)}
.imp-drop input{position:absolute; width:1px; height:1px; opacity:0}
.imp-bad{color:#B3261E; font-weight:600}
.imp-verdict{margin:10px 0; padding:12px 14px; border-radius:14px; font-weight:700}
.imp-verdict.bad{background:#FCE8E6; color:#8C1D18}
.imp-verdict.good{background:#E6F4EA; color:#1E5631}
.imp-list-h{margin:14px 0 6px; font-size:.95rem}
.imp-list{list-style:none; margin:0; padding:0; border:1px solid var(--line); border-radius:14px; overflow:hidden}
.imp-list li{display:flex; gap:12px; padding:9px 12px; border-top:1px solid var(--line); font-size:.92rem}
.imp-list li:first-child{border-top:0}
.imp-list b{flex:none; min-width:64px}
.imp-list.bad b{color:#B3261E}
.imp-list.look b{color:#8A5A00}
.imp-sum{display:grid; grid-template-columns:repeat(auto-fit, minmax(130px, 1fr)); gap:10px; margin:12px 0}
.imp-tile{padding:12px 14px; border:1px solid var(--line); border-radius:16px}
.imp-tile-v{font-size:1.35rem; font-weight:800}
.imp-tile-l{font-size:.8rem; color:var(--muted)}
@media (prefers-color-scheme:dark){ :root[data-theme=auto] .imp-verdict.bad{background:#3B1F1D; color:#FFB4AB} :root[data-theme=auto] .imp-verdict.good{background:#1E3326; color:#A8E6B5} :root[data-theme=auto] :is(.imp-bad,.imp-list.bad b){color:#FF8A80} :root[data-theme=auto] .imp-list.look b{color:#FFB162} }
:root[data-theme=dark] .imp-verdict.bad{background:#3B1F1D; color:#FFB4AB}
:root[data-theme=dark] .imp-verdict.good{background:#1E3326; color:#A8E6B5}
:root[data-theme=dark] :is(.imp-bad,.imp-list.bad b){color:#FF8A80}
:root[data-theme=dark] .imp-list.look b{color:#FFB162}
#imp-bar[hidden]{display:none}
/* Logo editor: background choices, fit button, preview on dark */
.biz-tools{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin:6px 2px}
.biz-dkp{display:flex; align-items:center; gap:8px; margin:0; font-weight:600; cursor:pointer}
.biz-dkp input,.biz-bg input[type=radio]{width:18px; height:18px; min-height:0; margin:0; padding:0; accent-color:var(--brand)}
.biz-hint{color:var(--muted); font-size:.82rem; margin:4px 2px 0}
.biz-bg{display:grid; gap:8px; margin:12px 2px 4px}
.biz-bg-t{font-weight:700}
.biz-seg{display:flex; gap:6px; flex-wrap:wrap}
.biz-seg label{display:flex; align-items:center; gap:8px; margin:0; padding:8px 12px; border:1px solid var(--line); border-radius:12px; cursor:pointer; font-weight:600; font-size:.9rem}
.biz-seg label:has(input:checked){background:var(--brand-soft); border-color:var(--brand)}
.biz-bg-row{display:flex; align-items:center; gap:12px; margin:0; font-weight:700}
.biz-bg-row[hidden],.biz-dkp[hidden]{display:none}
.biz-bg-row input[type=range]{flex:1; border:0; background:none; box-shadow:none; padding:0; min-height:0; height:28px; border-radius:0; accent-color:var(--brand)}
.biz-bg input[type=color]{width:48px; height:34px; min-height:0; padding:2px; border:1px solid var(--line); border-radius:10px; background:none; cursor:pointer}
.biz-dk .biz-stage{background:#0F1A17}
.biz-dk .biz-pc{background:#0F1A17; border-color:#2B3A36}
.biz-dk .biz-prev > div{background:#0F1A17; color:#fff; border-color:#2B3A36}
.biz-dk .biz-prev small{color:#9FB1AB}
