/* Account hub ("Web của tôi") + full-page create-web wizard. Tokens + shell
   from shared/ui.css; this file is layout only. */
/* The SẢNH customer app is a full-width dashboard (KPIs, web tables, advanced
   tiles, gauges), not a reading column — opt every customer page out of the
   shared .content max-width cap (fabric.css) so the main column fills the
   viewport with no trailing right gap. hub.css is loaded ONLY by the customer
   app, so CRM (crm.html) and CMS (cms.html) keep the readable cap. */
[data-skin="fabric"] .content { max-width: none; }
/* Requests filter tabs sit bare (pulled out of the card header) — space them from
   the section heading above and the table card below, like the web-console sub-nav. */
#reqTabs { margin: var(--sp-2) 0 var(--sp-3); }
/* Nav flush-left (active row hugs the sidebar edge, DN 09-09) now lives in the shared
   fabric .side .nav so hub/CRM/CMS match — no hub-local override here. */
/* Digotech mark + wordmark = sanh-digotech.html .brand (L136-141): inline svg badge, inline name. */
[data-skin="fabric"] .brand .dg-badge { width: 40px; height: 40px; flex: none; } /* ds-ok: design badge 40 */
[data-skin="fabric"] .dg-disc { fill: var(--logo); }
[data-skin="fabric"] .dg-piece { fill: var(--logo-ink); }
[data-skin="fabric"] .brand .bt { flex: none; }
[data-skin="fabric"] .brand .bt b { display: inline; }
[data-skin="fabric"] .brand .bt small { font-size: var(--fs-2xs); }
/* Body fills at least the viewport and the content grows, so short tabs keep
   the page background down to the bottom edge. */
body { background: var(--bg-subtle); min-height: 100vh; display: flex; flex-direction: column; }
/* width:100% is required: as a flex item with margin:0 auto, .wrap would otherwise
   shrink to its content width instead of filling the line — this restores the
   block behaviour (fill, then max-width caps and auto-margins centre it). */
body > .wrap { flex: 1 0 auto; width: 100%; }
.wrap { max-width: 1160px; margin: 0 auto; padding: 26px 24px 64px; overflow-x: clip; }

.eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); margin-bottom: 6px; }

.sub { color: var(--text-3); font-size: 13.5px; margin: 0; }
.hubhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 22px; }

/* ── web cards ── */
/* ── control-plane dashboard (hub) ── */
.hubwrap { position: relative; }
.hubwrap > *:not(.herodecor) { position: relative; z-index: 1; }
.herodecor { position: absolute; top: -24px; left: -24px; right: -24px; height: 260px; z-index: 0; pointer-events: none;
  background-image: radial-gradient(var(--border-strong) 1.1px, transparent 1.3px); background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(130% 100% at 28% -10%, #000 18%, transparent 68%);
  mask-image: radial-gradient(130% 100% at 28% -10%, #000 18%, transparent 68%); opacity: .55; }
@media (max-width: 720px) { .herodecor { display: none; } }
.statstrip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 0 0 22px; }
.stat { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 15px 18px; transition: border-color .14s, box-shadow .14s; }
.stat:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.stat-k { font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em; color: var(--text-3); margin-bottom: 8px; }
.stat-v { font-size: 27px; font-weight: 650; letter-spacing: -.02em; line-height: 1; }
@media (max-width: 620px) { .statstrip { grid-template-columns: 1fr 1fr; } }

.cardgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.webcard { position: relative; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; transition: transform .14s, border-color .14s, box-shadow .14s; }
.webcard::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--border-strong); transition: background .14s; z-index: 1; }
.webcard.p-slicesite::before { background: var(--accent); }
.webcard:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: 0 10px 28px var(--accent-soft); }
.webcard-open { display: block; width: 100%; text-align: left; background: transparent; border: 0; padding: 18px; cursor: pointer; font: inherit; color: inherit; }
.webcard-open h3 { margin: 0 0 4px; font-size: 16px; }
.webcard-open .host { color: var(--text-3); font-size: 12.5px; margin-bottom: 14px; word-break: break-all; }
.webcard-open .meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.webcard .go { position: absolute; top: 16px; right: 16px; color: var(--text-3); opacity: 0; transition: opacity .14s; }
.webcard:hover .go { opacity: 1; }
/* Members footer — a full-width bar so the divider spans the whole card. */
.webcard-members { display: flex; align-items: center; gap: 7px; padding: 11px 18px; border-top: 1px solid var(--border); color: var(--text-2); font-size: 12.5px; text-decoration: none; transition: background .14s, color .14s; }
.webcard-members:hover { background: var(--panel-2); color: var(--text); }
.webcard-members .ic { color: var(--text-3); }
.emptycard { grid-column: 1/-1; background: var(--panel); border: 1px dashed var(--border-strong); border-radius: 14px; padding: 40px 18px; text-align: center; color: var(--text-3); font-size: 13.5px; }

/* webs container + view toolbar (grid/list) + pager */
.webpanel { margin-bottom: 20px; }
.webpanel .ph { display: flex; align-items: center; }
.viewtools { margin-left: auto; }
 /* icon-only; inherits .theme-seg pill + .on active */
.webbody { padding: 16px; background: var(--panel); }
.phactions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.webbody .cardgrid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

.pgnum { font-family: var(--mono); font-size: 12.5px; color: var(--text-3); }

/* list view — one web per row */
.weblist { display: flex; flex-direction: column; gap: 10px; }
/* (legacy .webrow card component removed — it was dead and its ::before left-bar
   + border collided with the new list-view table rows, which reuse .webrow) */

.orders { margin-top: 20px; }

/* ── wizard (full page) ── */
.wizbar { margin-bottom: 14px; }
.wizhead { margin-bottom: 26px; }
.wizhead h1 { margin-bottom: 18px; }
.steps { list-style: none; display: flex; align-items: center; gap: 0; margin: 0; padding: 0; }
.steps li { display: flex; align-items: center; color: var(--text-3); font-size: 13px; }
.steps li:not(:last-child)::after { content: ""; width: 46px; height: 1px; background: var(--border-strong); margin: 0 14px; transition: background .18s; }
.steps li.done:not(:last-child)::after { background: var(--accent); } /* connector turns accent once the step is passed */
.steps .stepbtn { display: flex; align-items: center; gap: 9px; padding: 4px 12px 4px 4px; border: 1px solid transparent; border-radius: 999px; transition: .14s; }
.steps .sn { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 999px; font-family: var(--mono); font-size: 12.5px; background: var(--panel); border: 1px solid var(--border-strong); color: var(--text-3); transition: .14s; }
.steps li.done .sn, .steps li.on .sn { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.steps li.on .sl, .steps li.done .sl { color: var(--text); }
/* Hover on a reachable step: a soft pill around the whole number+label (like the account button) — never recolor the number. */
.steps li.reachable .stepbtn { cursor: pointer; }
.steps li.reachable:hover .stepbtn { border-color: var(--border-strong); background: var(--panel-2); }
/* A step that does not apply to the chosen flow (e.g. payment in custom design). */
.steps li.skip { opacity: .4; }
.steps li.skip .sn { text-decoration: line-through; }
.lead { color: var(--text-2); font-size: 14px; line-height: 1.6; max-width: 620px; margin: 0 0 22px; }
.lead a { color: var(--accent); }

/* platform cards */
.platgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.platcard { position: relative; text-align: left; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 22px 20px; cursor: pointer; font: inherit; color: inherit; transition: transform .14s, border-color .14s, box-shadow .14s; display: flex; flex-direction: column; }
.platcard:hover:not(:disabled) { transform: translateY(-2px); border-color: var(--accent); box-shadow: var(--shadow); }
/* DigoSite (recommended) card: no highlight border/ring (DN 09-16) — the "Khuyên
   dùng" badge alone marks it; the accent border+glow was removed. */
.platcard .platicon { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 11px; background: var(--accent-soft); color: var(--accent); margin-bottom: 14px; }
.platcard .platicon .ic { width: 22px; height: 22px; }
.platcard h3 { margin: 0 0 7px; font-family: var(--serif); font-weight: 600; font-size: 18px; letter-spacing: -.01em; display: flex; align-items: center; gap: 8px; }
.platcard p { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.55; }
.platcard.is-soon { opacity: .6; cursor: not-allowed; }
.badge-rec { position: absolute; top: 16px; right: 16px; font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; background: var(--accent); color: var(--accent-ink); }
h3 .soon { font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; padding: 2px 8px; border-radius: 999px; background: var(--panel-2); color: var(--text-3); }

/* theme picker (step 3) */
.themepanel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; }
.themebar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.themefilters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.themebar-right { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; }
.themeprice { width: auto; min-width: 120px; padding-right: 30px; flex: none; }
.themebar-right .themesearch { width: 260px; max-width: 40vw; }
@media (max-width: 640px) { .themebar-right { width: 100%; flex-wrap: wrap; } .themebar-right .themesearch { flex: 1; width: auto; max-width: none; } }

/* step 3 mode toggle + custom-design estimator */
.modeseg { display: inline-flex; gap: 4px; padding: 4px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 999px; margin-bottom: 16px; }
.modeseg button { border: 0; background: transparent; color: var(--text-2); font: inherit; font-size: 13px; font-weight: 550; padding: 7px 16px; border-radius: 999px; cursor: pointer; }
.modeseg button.on { background: var(--panel); color: var(--text); box-shadow: var(--shadow-sm); }
.estcols { display: grid; grid-template-columns: 1fr 320px; gap: 16px; align-items: start; }
.estform { display: flex; flex-direction: column; gap: 18px; }
.estgroup { display: flex; flex-direction: column; gap: 9px; }
.estglabel { font-size: 13px; font-weight: 600; color: var(--text-2); }
.estopts { display: flex; flex-wrap: wrap; gap: 8px; }
.estopt { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--border); background: var(--panel); color: var(--text); font: inherit; font-size: 13px; padding: 8px 13px; border-radius: var(--radius-sm); cursor: pointer; transition: border-color .14s, background .14s; }
.estopt:hover { border-color: var(--border-strong); }
.estopt.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-2); font-weight: 550; }
.eo-price { font-size: 11.5px; color: var(--text-3); font-family: var(--mono); }
.estopt.on .eo-price { color: var(--accent-2); }
.estsum { position: sticky; top: 16px; }
.estsum .estbody { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.estsum .estbody .hint { margin: 0; }
.estrange { font-size: 21px; margin: 0; letter-spacing: -.01em; }
.estrange b { font-weight: 650; }
.est-empty { font-size: 13px; color: var(--text-3); font-weight: 400; }
@media (max-width: 820px) { .estcols { grid-template-columns: 1fr; } .estsum { position: static; } }
.themetabs { display: flex; flex-wrap: wrap; gap: 6px; }
.themesearch { max-width: 300px; }
.themegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.themecard { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; transition: transform .14s, border-color .14s, box-shadow .14s; }
.themecard:hover { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow); }
.themecard.is-pick { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.themeprev { height: 130px; background: var(--panel-2); padding: 16px; display: flex; flex-direction: column; gap: 9px; }
.themeprev .tp-bar { height: 12px; width: 42%; border-radius: 4px; background: var(--accent); }
.themeprev .tp-line { height: 7px; width: 78%; border-radius: 4px; background: var(--border-strong); }
.themeprev .tp-line.short { width: 55%; }
.themeprev .tp-box { margin-top: auto; height: 42px; border-radius: 8px; background: var(--panel); border: 1px solid var(--border); }
.themebody { padding: 16px; }
.themehd { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 5px; }
.themehd h3 { margin: 0; font-size: 15px; }
.themebody p { margin: 0 0 10px; font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.themetags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.themepick { width: 100%; }

/* hosting plan cards — ported from CRM preview card */
.plangrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
/* Wizard step 2: 3 plan cards per row (→ 2 tablet, 1 mobile), like the upgrade picker. */
#planGrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 820px) { #planGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { #planGrid { grid-template-columns: 1fr; } }
.plancard { position: relative; overflow: hidden; text-align: left; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 20px; cursor: pointer; font: inherit; color: inherit; transition: transform .14s, border-color .14s, box-shadow .14s; display: flex; flex-direction: column; gap: 12px; }
/* Corner ribbon (hosting type) — diagonal filled band in the top-right corner.
   .ribclip is its own overflow:hidden box (matching the card's rounded rect) so
   the ribbon stays clipped to the corner even when a selected card switches to
   overflow:visible for its term drop — otherwise the band juts past the card. */
.plancard .ribclip { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
.planrib { position: absolute; top: 16px; right: -30px; width: 116px; transform: rotate(45deg); text-align: center; padding: var(--sp-1) 0; font-family: var(--mono); font-size: var(--fs-xs); font-weight: 600; letter-spacing: var(--ls-caps); text-transform: uppercase; box-shadow: var(--shadow); z-index: 2; } /* ds-ok: corner-ribbon geometry (rotate/offset/width) */
.planrib--shared { background: var(--surface-3); color: var(--text-2); }
.planrib--vps { background: var(--accent); color: var(--accent-ink); }
.plancard:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: var(--shadow); }
.plancard .pname { font-weight: 600; font-size: 15px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.plancard .price { font-family: var(--mono); font-size: 22px; font-weight: 700; letter-spacing: -.02em; }
.plancard .price small { font-size: 12px; color: var(--text-3); font-weight: 400; letter-spacing: 0; }
/* Spec box (DN 2026-09-20): same language as the web-list card — inset panel with
   label·mono-value rows, then a short included-features line for SSL/backups. */
.plancard .specbox { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); }
.plancard .specbox .srow { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-sm); }
.plancard .specbox .srow .k { color: var(--text-3); display: inline-flex; align-items: center; gap: var(--sp-2); }
.plancard .specbox .srow .k > .ic { color: var(--text-3); flex: none; }
.plancard .specbox .srow .v { font-family: var(--mono); font-size: var(--fs-sm); color: var(--text); font-weight: 500; white-space: nowrap; }
.plancard .specbox .srow .v .inf { font-size: var(--fs-md); }
.plancard .pc-feats { display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--text-2); }
.plancard .pc-feats > div { display: flex; align-items: center; gap: var(--sp-2); }
.plancard .pc-feats .ic { color: var(--good); flex: none; }
/* .choose is a real <button> (the card is a div holding inputs). It wears the spec
   box's surface+border at rest and fills accent on card hover / when selected
   (DN 2026-09-20). appearance:none so the fill paints, not native chrome. */
.plancard .choose { width: 100%; margin-top: var(--sp-1); display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); font-size: 13px; font-weight: 600; color: var(--text); padding: 9px; border: 1px solid var(--line); border-radius: var(--radius-sm); transition: .14s; -webkit-appearance: none; appearance: none; background: var(--surface-2); font-family: inherit; cursor: pointer; }
.plancard .choose .ic { flex: none; }
.plancard:hover .choose, .plancard.sel .choose { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.plancard { align-self: start; } /* a selected card grows with its term box without stretching row-mates */
.plancard.sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.plancard.sel:hover { transform: none; } /* holds a form now — don't lift on hover */
/* Subscription-term box, revealed inside the selected card between the feature
   list and the button (the card's own gap keeps it evenly spaced). */
/* Term box is shared by the wizard's plan cards and the hub renewal modal. */
:is(.plancard, .sl-modal) .upgterm { border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 12px 13px; background: var(--bg-subtle); }
:is(.plancard, .sl-modal) .tmrow { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
:is(.plancard, .sl-modal) .tmlbl { font-size: 12.5px; font-weight: 600; }
:is(.plancard, .sl-modal) .tmqtybox>.tmqty { width: calc(46px + var(--h-xs)); text-align: center; padding-left: 6px; } /* ds-ok: 46px = old 2-digit box width (unchanged); + ▲▼ column from shared .stepper (fabric.css) */
:is(.plancard, .sl-modal) .tmqtybox:has(.tmstep[hidden]) .tmqty { padding-right: 6px; }
/* Match the qty box: same border colour + radius (not the pill default). */
:is(.plancard, .sl-modal) .tmunit { width: auto; border-color: var(--border-strong); border-radius: var(--radius-sm); }
:is(.plancard, .sl-modal) .tmunit .tmu { border-radius: calc(var(--radius-sm) - 3px); }
:is(.plancard, .sl-modal) .tmhint { width: 100%; font-size: 11.5px; color: var(--text-3); }
:is(.plancard, .sl-modal) .tmtotal { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--text-2); }
:is(.plancard, .sl-modal) .tmtotal b { font-family: var(--mono); font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -.02em; }

/* Create-web wizard plan cards: same picker UX as the web-console upgrade panel —
   equal-height cards, and selecting one drops an absolute term/continue panel
   (one ::before border, no seam) instead of growing the card and pushing the grid.
   Ported from web-console.css; scoped to #planGrid. */
#planGrid .plancard { align-self: stretch; }
#planGrid .plancard > ul { flex: 1 1 auto; }
#planGrid .plancard > .upgdrop { display: none; }
#planGrid .plancard.sel { align-self: start; border: 0; background: transparent; padding-bottom: 0; overflow: visible; position: relative; z-index: 20; box-shadow: none; }
#planGrid .plancard.sel:hover { transform: none; box-shadow: none; }
#planGrid .plancard.sel > .choose { display: none; }
#planGrid .plancard.sel::before { content: ""; position: absolute; left: 0; top: 0; right: 0; height: var(--selh, 100%); background: var(--panel); border: 1px solid var(--accent); border-radius: 14px; box-shadow: 0 18px 30px -24px rgba(52, 40, 20, .42); z-index: -1; pointer-events: none; }
#planGrid .plancard.sel > .upgdrop { display: block; position: absolute; left: 0; right: 0; top: 100%; background: transparent; border: 0; padding: 16px 20px 20px; z-index: 1; }
#planGrid .upgdrop > .upgterm { margin-top: 0; border: 0; background: transparent; padding: 0; }
#planGrid .bdlbl { display: inline-flex; align-items: center; gap: 5px; }
#planGrid .upgdrop .paybtn { width: 100%; margin-top: 12px; text-align: center; font-size: 13px; font-weight: 550; color: var(--accent-ink); background: var(--accent); border: 1px solid var(--accent); border-radius: var(--radius-sm); padding: 9px; cursor: pointer; -webkit-appearance: none; appearance: none; font-family: var(--serif); }
#planGrid .upgdrop .paybtn:hover:not(:disabled) { filter: brightness(1.04); }

/* Hub renewal modal: centered dialog over a scrim (no modal infra existed). */
.sl-modal-ovl { position: fixed; inset: 0; z-index: var(--z-overlay); display: grid; place-items: center; padding: 20px; background: var(--backdrop); backdrop-filter: blur(var(--backdrop-blur)); opacity: 0; pointer-events: none; transition: opacity .16s; }
.sl-modal-ovl.open { opacity: 1; pointer-events: auto; }
.sl-modal { width: 380px; max-width: 100%; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow-lg, 0 12px 40px rgba(0,0,0,.2)); transform: translateY(6px); transition: transform .16s; }
.sl-modal-ovl.open .sl-modal { transform: none; }
.sl-modal .mh { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.sl-modal .mh h3 { margin: 0; font-size: 15px; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sl-modal .mx { margin-left: auto; flex: none; display: grid; place-items: center; width: 30px; height: 30px; border: 0; border-radius: 8px; background: transparent; color: var(--text-3); cursor: pointer; }
.sl-modal .mx:hover { background: var(--panel-2); color: var(--text); }
.sl-modal .mb { padding: 16px; }
.sl-modal .mf { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); }

/* step 3: form + review */
.reviewcols { display: grid; grid-template-columns: 1fr 300px; gap: 20px; align-items: start; }
.reviewform { display: flex; flex-direction: column; gap: 14px; }
/* WP create-form field groups follow the same 14px field rhythm as .reviewform
   (they're wrappers, so the gap doesn't cascade from the parent). */
#cwWpFields, #cwDbFields { display: flex; flex-direction: column; gap: var(--field-gap); }
.frow { display: flex; flex-direction: column; gap: 6px; }
.frow label { font-size: 12.5px; color: var(--text-2); font-weight: 500; }
textarea.input { resize: vertical; line-height: 1.5; }
/* Multi-root address picker (create-web wizard): [sub].[root] on one line, the
   assembled host / validation note in mono underneath. Bare selectors — hub.css
   only loads on the geology pages and the ids are unique to the hub wizard. */
.subpick { display: flex; align-items: center; gap: 6px; }
.subpick #wSub { flex: 1 1 auto; min-width: 0; }
.subpick #wRoot { flex: 0 1 auto; max-width: 48%; }
.subpick .subsep { font-family: var(--mono); color: var(--text-3); }
.subnote { display: block; margin-top: 5px; font-family: var(--mono); font-size: 12px; color: var(--text-3); min-height: 1em; }
.subnote.bad { color: var(--crit); }
.rc-row .dom { font-family: var(--mono); }
/* Self-serve create-web (#51): reuses .subpick; adds the "building…" spinner so
   the customer sees the provision is running (was missing — DN 2026-09-04). */
.cwform { max-width: 34rem; } /* ds-ok: single-column form readable width (one-off) */
/* Inline create-web panel — opens in place of the web grid (no page swap). */
.cwpanel { margin-top: var(--sp-4); }
.cwphead { display: flex; align-items: flex-start; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.cwphead h2 { font-family: var(--display); font-size: var(--fs-xl); margin: 0; line-height: 1.2; }
.cwphead .lead { margin: var(--sp-1) 0 0; color: var(--text-2); font-size: var(--fs-md); }
.cwloading { display: none; align-items: center; gap: 10px; margin-top: 18px; font-family: var(--mono); font-size: 13px; color: var(--text-2); } /* ds-ok: one-off gap above the building indicator */
.cwloading:not([hidden]) { display: flex; }
.cwspin { width: 18px; height: 18px; border: 2px solid var(--border-strong); border-top-color: var(--accent); border-radius: 50%; animation: cwspin .8s linear infinite; } /* ds-ok: loading spinner ring (one-off decorative) */
@keyframes cwspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cwspin { animation: none; } }
.reviewcard { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; overflow: hidden; position: sticky; top: 76px; }
.reviewcard .rc-head { padding: 13px 16px; border-bottom: 1px solid var(--border); font-size: 12px; font-family: var(--mono); letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); }
.reviewcard .rc-row { padding: 13px 16px; display: flex; justify-content: space-between; gap: 12px; font-size: 13px; border-bottom: 1px solid var(--border); }
.reviewcard .rc-row:last-child { border-bottom: 0; }
.reviewcard .rc-pay { padding: 14px 16px; border-top: 1px solid var(--border); }
.reviewcard .rc-row .k { color: var(--text-3); }
.reviewcard .rc-row .v { color: var(--text); font-weight: 550; text-align: right; }
.reviewcard .rc-total .v { font-family: var(--mono); font-size: 16px; }
/* Order-summary extras: the date range under the term, and the VAT note. */
.rc-row .k { white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; } /* one line; vertically centers an inline (i) icon with the text */
.rc-row .v small { display: block; margin-top: 2px; color: var(--text-3); font-weight: 400; white-space: nowrap; } /* date range drops below the term value */
.rc-note { padding: 10px 16px; font-size: 11.5px; color: var(--text-3); border-top: 1px dashed var(--border); }
/* Small (i) icon + hover tooltip (e.g. the VAT explainer). */
.infotip { position: relative; display: inline-flex; align-items: center; vertical-align: middle; color: var(--text-3); cursor: help; }
.infotip:hover, .infotip:focus { color: var(--accent); outline: none; }

/* ── One tooltip for the whole hub (system-wide later). ──
   tooltip.js renders a single .sl-tip appended to <body> for any [data-tip]
   element (and the .infotip (i) icons, which now carry data-tip too). Because it
   is position:fixed on <body>, it escapes every overflow:hidden card AND flips
   above/below + clamps left/right to stay inside the viewport on all four edges.
   One bubble look = the standard style; no more native `title` tooltip. */
.sl-tip { position: fixed; z-index: 9999; max-width: 240px; background: var(--panel); color: var(--text); border: 1px solid var(--border); box-shadow: var(--shadow); font-size: 11.5px; font-weight: 400; line-height: 1.45; letter-spacing: 0; text-align: left; white-space: normal; padding: 7px 10px; border-radius: 8px; opacity: 0; pointer-events: none; transition: opacity .12s; }
.sl-tip.on { opacity: 1; }

/* Account → Sessions & devices list */
.sesslist { display: flex; flex-direction: column; gap: 8px; }
.sessrow { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--panel); }
.sess-ic { flex: none; width: 34px; height: 34px; border-radius: 999px; display: grid; place-items: center; background: var(--panel-2); color: var(--text-2); }
.sess-ic .ic { width: 18px; height: 18px; }
.sess-info { flex: 1; min-width: 0; }
.sess-dev { font-size: 13px; font-weight: 550; color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sess-cur { font-size: 10.5px; font-weight: 600; color: var(--good); background: var(--good-soft); border-radius: 999px; padding: 1px 8px; letter-spacing: .02em; }
.sess-meta { font-size: 12px; color: var(--text-3); font-family: var(--mono); margin-top: 2px; word-break: break-all; }
.sess-revoke { flex: none; }
.sess-empty { font-size: 13px; color: var(--text-3); padding: 6px 2px; }

/* Account → Two-factor (2FA) */
.twofa .tfa-row { display: flex; align-items: center; gap: 12px; }
.twofa .tfa-badge { display: inline-flex; align-items: center; font-size: 12px; font-weight: 600; color: var(--good); background: var(--good-soft); border-radius: 999px; padding: 3px 12px; }
.twofa .tfa-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.twofa .tfa-danger { color: var(--crit); border-color: color-mix(in srgb, var(--crit) 40%, var(--border)); }
.twofa .tfa-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 12px; font-size: 13px; color: var(--text-2); }
.twofa .tfa-qr { display: block; background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 8px; margin: 8px 0; max-width: 200px; }
.twofa .tfa-key { font-family: var(--mono); font-size: 15px; letter-spacing: .12em; background: var(--bg-subtle); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; margin: 8px 0 6px; word-break: break-all; color: var(--text); }
.twofa .tfa-otpauth { font-size: 12px; color: var(--accent-2); text-decoration: none; }
.twofa .tfa-otpauth:hover { text-decoration: underline; }
.twofa .tfa-codes { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; }
.twofa .tfa-codes code { font-family: var(--mono); font-size: 13.5px; text-align: center; background: var(--bg-subtle); border: 1px solid var(--border); border-radius: 8px; padding: 7px 4px; letter-spacing: .04em; }

/* Tablet and down: drop the account name AND the chevron, and compact the button
   to a clean avatar circle (same as mobile) so nothing overflows the topbar. */
@media (max-width: 1024px) {
  .topbar .acctname, .topbar .acctbtn > svg { display: none; }
  .topbar .acctbtn { width: 34px; padding: 3px; justify-content: center; }
}
.paynote { background: var(--bg-subtle); border: 1px solid var(--border); border-radius: 14px; padding: 16px; }
.paynote h4 { margin: 0 0 6px; font-size: 13.5px; }
.paynote p { margin: 0; font-size: 13px; color: var(--text-2); line-height: 1.6; }
#confirmRows .rc-row, #doneRows .rc-row { padding: 12px 16px; display: flex; justify-content: space-between; gap: 12px; font-size: 13px; border-bottom: 1px solid var(--border); }
#confirmRows .rc-row:last-child, #doneRows .rc-row:last-child { border-bottom: 0; }
#confirmRows .rc-row .k, #doneRows .rc-row .k { color: var(--text-3); }
#confirmRows .rc-row .v, #doneRows .rc-row .v { color: var(--text); font-weight: 550; text-align: right; }
#confirmRows .rc-total .v, #doneRows .rc-total .v { font-family: var(--mono); font-size: 15px; }
#doneRows { border-top: 1px solid var(--border); }
.wizfoot { display: flex; align-items: center; gap: 12px; margin-top: 22px; }
.formmsg { font-size: 12.5px; color: var(--text-3); }

.btn--primary { box-shadow: 0 1px 2px rgba(12,14,22,.14), inset 0 1px 0 rgba(255,255,255,.14); }

@media (max-width: 720px) {
  .reviewcols { grid-template-columns: 1fr; }
  .reviewcard { position: static; }
  .steps .sl { display: none; }
  .steps li:not(:last-child)::after { width: 24px; margin: 0 8px; }
}

/* ── account page ── */
.acct { max-width: 1160px; }
/* Settings-style layout: a vertical tab menu on the left, the active section's
   content on the right — no long scroll to reach a section. Each pane is one
   section (or a pair of short forms) so it fits roughly one screen. */
.acctlayout { display: grid; grid-template-columns: 236px 1fr; gap: 24px; align-items: start; margin-top: 10px; }
.acctnav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 20px; }
.acctnav button { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 9px 12px; border: 0; background: transparent; border-radius: 9px; color: var(--text-2); font: inherit; font-size: 13.5px; cursor: pointer; transition: background .14s, color .14s; }
.acctnav button .ic { color: var(--text-3); flex: none; transition: color .14s; }
.acctnav button:hover { background: var(--panel-2); color: var(--text); }
.acctnav button.on { background: var(--accent-soft); color: var(--text); }
.acctnav button.on .ic { color: var(--accent); }
.acctpane { display: none; }
.acctpane.on { display: block; }
.acctcols { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 860px) {
  .acctlayout { grid-template-columns: 1fr; gap: 14px; }
  .acctnav { flex-direction: row; overflow-x: auto; position: static; gap: 4px; padding-bottom: 2px; }
  .acctnav button { width: auto; white-space: nowrap; }
  .acctcols { grid-template-columns: 1fr; }
}
.acctbody { padding: 16px; display: flex; flex-direction: column; gap: 14px; }
.acctbody .frow { display: flex; flex-direction: column; gap: 6px; }
.acctbody label { font-size: 12.5px; color: var(--text-2); font-weight: 500; }
.acctbody .hint { font-size: 11.5px; color: var(--text-3); }
.acctbody .input:disabled { background: var(--panel-2); color: var(--text-3); cursor: not-allowed; }
.acctfoot { display: flex; align-items: center; gap: 11px; margin-top: 2px; }
/* Users & roles pane (team.js): header carries the invite button; rows reuse .sessrow */
.acctpane[data-pane="team"] .ph { justify-content: space-between; align-items: center; }
.acctpane[data-pane="team"] .acctcard + .acctcard { margin-top: var(--sp-4); }
.acctpane[data-pane="team"] .sess-ic { font-family: var(--display); font-size: var(--fs-xs); font-weight: 700; color: var(--accent); }
.acctpane[data-pane="team"] .sessrow .dsel { flex: none; min-width: var(--w-dsel-min); }
.tm-does { font-size: var(--fs-sm); color: var(--text-3); margin-top: 2px; line-height: 1.5; }
.tm-webs { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-2); }
@media (max-width: 640px) { .acctpane[data-pane="team"] .sessrow { flex-wrap: wrap; } .acctpane[data-pane="team"] .sess-info { flex-basis: calc(100% - var(--h-ctl) - var(--sp-3)); } }

/* Language pane: label + dropdown on one centered row. fabric.js upgrades the
   native <select class="input"> into a .dsel (the <select> is hidden), so size the
   .dsel — and keep the bare <select> sized too as a no-JS fallback. */
.acctbody .frow--inline { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.acctbody .frow--inline label { margin: 0; }
.acctbody .frow--inline .dsel { flex: none; min-width: var(--w-dsel-min); }
.acctbody .frow--inline > select.input { width: auto; min-width: var(--w-dsel-min); }
/* The .dsel dropdown panel is position:absolute and would be clipped by the base
   [data-skin] .panel overflow:hidden; account setting cards hold only forms, so let
   it escape. Skin-prefixed to outrank the base .panel rule (same specificity tier). */
[data-skin="fabric"] .acctcard { overflow: visible; }

/* Danger zone (delete account): right-pane content only, sub-nav item styled as normal */
.acctcard--danger { border-color: color-mix(in srgb, var(--crit) 34%, var(--border)); }
.acctcard--danger .ph h4 { color: var(--crit); }
.del-warn { font-size: 13px; line-height: 1.55; color: var(--text); background: var(--crit-soft); border: 1px solid color-mix(in srgb, var(--crit) 30%, var(--border)); border-radius: var(--radius-sm); padding: 11px 13px; margin: 0; }
.btn--danger { background: var(--crit); border-color: var(--crit); color: #fff; }
.btn--danger:hover:not(:disabled) { filter: brightness(1.06); }
.btn--danger:disabled { opacity: .5; cursor: not-allowed; }

/* ── platform comparison — same "core-slice" rows as the SẢNH requests table ── */
.platcompare { margin-top: 26px; }
/* labelled divider between the platform cards and the comparison table */
.pcmp-div { display: flex; align-items: center; gap: 16px; margin: 0 0 18px; }
.pcmp-div::before, .pcmp-div::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.pcmp-div span { font-family: var(--mono); font-size: 13px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--text-2); }
.pcmp-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r-md); } /* ds-ok: outer table frame (DN 09-16) */
/* collapsible variant (create-web wizard, DN 09-16): clickable divider + chevron,
   starts closed. Label typography mirrors .pcmp-div span above. */
.pcmp-det { margin: 0; }
.pcmp-sum { display: flex; align-items: center; gap: var(--sp-4); margin: 0; padding: var(--sp-2) 0; cursor: pointer; list-style: none; }
.pcmp-sum::-webkit-details-marker { display: none; }
.pcmp-sum::before, .pcmp-sum::after { content: ""; flex: 1; height: 1px; background: var(--border); } /* ds-ok: hairline divider, same as .pcmp-div */
.pcmp-sum-in { display: inline-flex; align-items: center; gap: var(--sp-2); font-family: var(--mono); font-size: var(--fs-body-sm); font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--text-2); } /* ds-ok: label mirrors .pcmp-div span */
.pcmp-sum:hover .pcmp-sum-in { color: var(--text); }
.pcmp-chev { width: var(--fs-md); height: var(--fs-md); flex: none; transition: transform var(--t-base) var(--ease); }
.pcmp-det[open] .pcmp-chev { transform: rotate(180deg); }
.pcmp-det[open] .pcmp-sum { margin-bottom: var(--sp-4); }

.pcmp-crit, .pcmp-hd { display: inline-flex; align-items: center; gap: 8px; }
.pcmp-ic { width: 15px; height: 15px; flex: none; color: var(--text-3); }
/* row-header (criterion) cells left-aligned — <th scope=row> defaults to centre (DN 09-16) */
.pcmp tbody th { text-align: left; padding: 11px 14px; font-weight: 600; color: var(--text); } /* ds-ok: padding matches .tbl tbody td so the column lines up */
/* Framed table + ONE clean divider per row (DN 09-16). The base .tbl gives td a
   faint line-soft bottom (and NONE on the row-header th) — override both cells to a
   single --border line so it spans the full width and never doubles; the last row
   clears it so it doesn't sit on top of the .pcmp-wrap frame. */
/* Scoped like fabric's compiled .tbl rules ([data-skin=fabric] prefix) so it
   out-specifies the base line-soft td border — an unscoped .pcmp rule loses to it. */
[data-skin="fabric"] .pcmp.tbl tbody th, [data-skin="fabric"] .pcmp.tbl tbody td { border-bottom: 1px solid var(--border); } /* ds-ok: single row divider */
[data-skin="fabric"] .pcmp.tbl tbody tr:last-child th, [data-skin="fabric"] .pcmp.tbl tbody tr:last-child td { border-bottom: 0; }

/* ── FAQ accordion (Help page) ── */
.faq { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }
.faq-item { border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel); overflow: hidden; }
.faq-q { width: 100%; text-align: left; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border: 0; background: transparent; font: inherit; font-family: var(--serif); font-weight: 550; font-size: 15px; color: var(--text); cursor: pointer; }
.faq-q:hover { background: var(--panel-2); }
.faq-q .fa-chev { flex: none; color: var(--text-3); transition: transform .18s; }
.faq-item.open .faq-q .fa-chev { transform: rotate(180deg); }
.faq-a { padding: 8px 16px 16px; font-size: 13.5px; line-height: 1.65; color: var(--text-2); }
.faq-a p { margin: 0 0 8px; }
.faq-sec { font-family: var(--serif); font-weight: 600; font-size: 15px; color: var(--text-3); margin: 22px 0 8px; }

/* ── account menu (hub topbar) ── */
/* Notifications bell */
.notifwrap { position: relative; }
.notifbtn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; background: var(--panel); border: 1px solid var(--border); border-radius: 999px; color: var(--text-2); cursor: pointer; transition: border-color .14s, background .14s; }
.notifbtn:hover { background: var(--panel-2); border-color: var(--border-strong); color: var(--text); }
.notifdot { position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--crit); color: #fff; font-size: 10px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; border: 2px solid var(--bg-subtle); }
.notifdrop { position: absolute; top: calc(100% + 9px); right: 0; width: 360px; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); overflow: hidden; z-index: 30; }
.nd-head { display: flex; align-items: center; justify-content: space-between; padding: 13px 16px 9px; }
.nd-head b { font-size: 16px; letter-spacing: -.01em; }
.nd-head a { font-size: 12.5px; color: var(--accent); text-decoration: none; }
.nd-head a:hover { text-decoration: underline; }
/* Capped at 6 items in JS → no scroll, no scrollbar (rest on the full page). */
.nd-scroll { padding: 0 6px 4px; }
.nd-sec { padding: 8px 10px 4px; font-size: 12.5px; font-weight: 650; color: var(--text); }
.nd-foot { display: block; text-align: center; padding: 11px; border-top: 1px solid var(--border); font-size: 13px; font-weight: 550; color: var(--accent); text-decoration: none; background: var(--panel); }
.nd-foot:hover { background: var(--panel-2); }
/* one notification row (bell + page) — icon+text vertically centred; unread is a
   dot on the right only (no fill); background appears on hover. */
.ni { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 10px; font-size: 13px; line-height: 1.4; color: var(--text); text-decoration: none; position: relative; }
.ni:hover { background: var(--panel-2); }
.ni-ic { flex: none; width: 26px; height: 26px; border-radius: 999px; display: grid; place-items: center; background: var(--panel-2); color: var(--text-2); }
.ni-ic.ni-quoted { background: var(--accent-soft); color: var(--accent-2); }
.ni-ic.ni-paid { background: var(--good-soft); color: var(--good); }
.ni-ic.ni-ready { background: var(--good-soft); color: var(--good); }
.ni-text { flex: 1; min-width: 0; }
.ni-text.ni-cta { color: var(--accent-2); font-weight: 550; }
.ni-dot { flex: none; width: 8px; height: 8px; border-radius: 999px; background: var(--accent); }
.notifempty { padding: 26px 12px; text-align: center; color: var(--text-3); font-size: 13px; }
/* full /notifications page list */
.notifpage { padding: 8px; }
.notifpage .ni { padding: 13px 12px; font-size: 13.5px; border-radius: 12px; }
.notifpage .nd-sec { padding: 10px 12px 6px; font-size: 13px; }
.acctmenu { position: relative; }
.acctbtn { display: inline-flex; align-items: center; gap: 8px; height: 34px; background: var(--panel); border: 1px solid var(--border); cursor: pointer; font: inherit; color: var(--text); padding: 3px 10px 3px 3px; border-radius: 999px; transition: border-color .14s, background .14s; }
.acctbtn:hover { background: var(--panel-2); border-color: var(--border-strong); }
.avatar { width: 26px; height: 26px; border-radius: 999px; background: var(--accent); color: var(--accent-ink); display: grid; place-items: center; font-size: 12px; font-weight: 600; flex: none; }
.acctname { font-size: 13px; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acctdrop { position: absolute; top: calc(100% + 9px); right: 0; min-width: 200px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); padding: 6px; z-index: 30; }
.acctdrop .who { padding: 8px 10px 10px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.acctdrop .who .n { font-size: 13.5px; font-weight: 550; }
.acctdrop .who .e { font-size: 12px; color: var(--text-3); word-break: break-all; }
.acctdrop a, .acctdrop button { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 8px 10px; border-radius: 8px; font: inherit; font-size: 13px; color: var(--text-2); background: transparent; border: 0; cursor: pointer; text-decoration: none; }
.acctdrop a:hover, .acctdrop button:hover { background: var(--panel-2); color: var(--text); }

/* ── payment page ── */
#payRows .rc-row { padding: 12px 16px; display: flex; justify-content: space-between; gap: 12px; font-size: 13px; border-bottom: 1px solid var(--border); }
#payRows .rc-row:last-child { border-bottom: 0; }
#payRows .rc-row .k { color: var(--text-3); }
#payRows .rc-row .v { color: var(--text); font-weight: 550; text-align: right; }
#payRows .rc-total .v { font-family: var(--mono); font-size: 15px; }
.paytabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.paytab { border: 1px solid var(--border); background: var(--panel); border-radius: 999px; padding: 6px 13px; font: inherit; font-size: 12.5px; color: var(--text-2); cursor: pointer; transition: .14s; }
.paytab.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
/* Pay page: order summary and payment method sit side by side (stack on narrow).
   margin-top: the subtitle above has no bottom margin, so give the grid breathing
   room instead of sitting flush under the "Chọn phương thức…" line. */
#payView { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; margin-top: 20px; }
#payView > section { margin: 0; }
@media (max-width: 860px) { #payView { grid-template-columns: 1fr; } }
.bankgrid { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.bankinfo { flex: 1 1 var(--w-dsel-min); min-width: 0; } /* wraps under the QR when the card is narrow (2-column pay page) */
.qrbox { width: 216px; height: 216px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 12px; background: #fff; padding: 8px; }
.qrbox img { width: 200px; height: 200px; object-fit: contain; }
.bankinfo .brow { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.bankinfo .bk { color: var(--text-3); }
.bankinfo .bv { color: var(--text); font-weight: 550; }
.bankinfo .hint { font-size: 12px; color: var(--text-3); margin: 12px 0; line-height: 1.5; }
.simnote { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; color: var(--text-2); margin-bottom: 14px; }
.paidmark { width: 52px; height: 52px; border-radius: 999px; background: var(--good-soft); color: var(--good); display: grid; place-items: center; margin: 0 auto; }
.paidmark .ic { width: 26px; height: 26px; stroke-width: 2.4; }
@media (max-width: 620px) { .bankgrid { grid-template-columns: 1fr; } .qrbox { margin: 0 auto; } }

/* ── page head ── */
/* Round back button — one circular arrow, sits INLINE before the page title. */
.backbtn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--panel); color: var(--text-2); text-decoration: none; transition: background .14s, color .14s, border-color .14s; cursor: pointer; flex: none; }
.backbtn:hover { background: var(--panel-2); color: var(--text); border-color: var(--text-3); }
.backbtn--sm { width: 30px; height: 30px; }
/* Title row: small round back button, then the heading. */
.pagehead { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.pagehead h1 { margin: 0; }

/* ============================================================================
   Sảnh — ported from DN's Design-System artifact (flat, token-driven).
   Reuses ui.css primitives (.btn, .pill, .panel); adds the KPI / kicker /
   section-card / web-card / requests-table components. This block is last so it
   wins the cascade over the older hub layout above.
   ========================================================================== */
.brand .brandlogo{width:28px;height:28px;border-radius:8px;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center;flex:none}
.brand{display:flex;align-items:center;gap:9px}
.brand .brandlogo .ic{width:17px;height:17px}

::-webkit-scrollbar{ width:var(--scroll-w); height:var(--scroll-w); } /* bare = the ROOT/viewport bar; fabric's scoped thumb can't reach it (descendant combinator) */
::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:var(--r-pill); }
::-webkit-scrollbar-track{ background:transparent; }

::-webkit-scrollbar-button{ display:none; }

/* Tổng quan › Việc cần bạn làm + Hoạt động gần đây (#157 Đ1) — measured against the app design (#161, _design/checks/sanh-overview.json) */
/* app design .title — "Chào <tên>" one line, summary under it */
.ovtitle { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px var(--sp-3); margin-bottom: 22px; } /* ds-ok: design .title gaps */
.ovtitle h1 { margin: 0; font: 650 clamp(var(--fs-2xl), 2.4vw, var(--fs-3xl))/1.1 var(--display); letter-spacing: -0.02em; color: var(--ink); } /* ds-ok: design title scale */
.ovtitle p { flex-basis: 100%; margin: 0; color: var(--muted); max-width: 64ch; text-wrap: pretty; } /* ds-ok: design measure */
/* app design .card + .card-h */
.ovcard { padding: 20px; } /* ds-ok: design card padding */
.ovh { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); margin-bottom: 14px; } /* ds-ok: design card-h gap */
.ovh > div { min-width: 0; }
.ovh h2 { margin: 0; font: 600 var(--fs-title)/1.3 var(--sans); letter-spacing: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ovh small { display: block; margin: 2px 0 0; color: var(--muted); font-size: var(--fs-sm); } .ovh small:empty { display: none; } /* ds-ok: design sub gap */
.ovh > a { font-size: var(--fs-sm); color: var(--muted); }
.ovh > a:hover { color: var(--ink); }
.ovh > a.go { font-size: var(--fs-md); display: inline-grid; place-items: center; flex: none; width: 30px; height: 30px; border-radius: var(--r-sm); text-decoration: none; } .ovh > a.go:hover { background: var(--side-hover); } .ovh > a.go svg { width: var(--ic-lg); height: var(--ic-lg); } /* ds-ok: design card-h link 30 */
/* app design .next — the to-do rows, the first one tinted */
.next { display: grid; gap: 10px; } /* ds-ok: design next gap */
.next__item { display: grid; gap: var(--sp-2); padding: 14px; border-radius: var(--r-md); border: 1px solid var(--hair); } /* ds-ok: design next item */
.next__item.first { background: var(--primary-soft); border-color: transparent; }
.next__item b { display: flex; align-items: center; gap: var(--sp-2); font-weight: 600; }
.next__item b .ic { width: var(--ic-mid); height: var(--ic-mid); }
.next__item p { margin: 0; font-size: var(--fs-ui); color: var(--muted); } .next__item.first p { color: var(--primary-text); }
.next__item .btn { justify-self: start; }

/* Thanh toán › kết quả chuyển khoản (#157 Đ1): note above the QR + "wrong memo" link */
.paynote { margin-bottom: var(--sp-4); align-items: center; flex-wrap: wrap; }
.paywrong { display: flex; margin-top: var(--sp-2); padding-inline: 0; white-space: normal; text-align: start; height: auto; }

/* ===== Khách Đ3/Đ4 (#133): Web đang làm · Thanh toán · Hợp đồng & hoá đơn — port of
   sanh-digotech.html (decision 161). Scoped to .dg so the older acct pages keep their rules. ===== */
.dg .card { padding: var(--pad); font-size: var(--fs-base); line-height: 1.5; }
.dg .card.flush { padding: 0; overflow: hidden; }
.dg .ic { width: var(--ic-lg); height: var(--ic-lg); }
.dg .ic-sm { width: var(--ic-mid); height: var(--ic-mid); }
.dg .grid { display: grid; gap: var(--sp-4); }
.dg .g-side { grid-template-columns: minmax(0, 1fr) 340px; align-items: start; } /* ds-ok: design side column */
.dg .stack { display: grid; gap: var(--sp-4); }
.dg .card-h { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); margin-bottom: 14px; } /* ds-ok: design card-h */
.dg .card-h > div { min-width: 0; }
.dg .card-h h2 { margin: 0; font: 600 var(--fs-title)/1.3 var(--sans); letter-spacing: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dg .card-h p { margin: 2px 0 0; color: var(--muted); font-size: var(--fs-sm); } /* ds-ok: design sub gap */
.dg .card-h > a { color: var(--muted); display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: var(--r-sm); text-decoration: none; flex: none; } /* ds-ok: design card-h link 30 */
.dg .card-h > a:hover { background: var(--side-hover); color: var(--ink); }
.dg .card__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: var(--sp-4); padding-top: 14px; border-top: 1px solid var(--hair); } /* ds-ok: design card foot */
.dg .muted { color: var(--muted); }
.dg .mono { font-family: var(--mono); font-size: var(--fs-sm); }
.dg .mono .btn { font-family: inherit; }
.dg .num { font-family: var(--sans); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dg .rows, .dg .list, .dg .checks, .dg .lines { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.dg .rows > li { display: flex; align-items: center; gap: 14px; padding: 13px 2px; border-bottom: 1px solid var(--hair); } /* ds-ok: design rows */
.dg .list > li { display: flex; align-items: center; gap: var(--sp-3); padding: 11px 2px; border-bottom: 1px solid var(--hair); min-width: 0; } /* ds-ok: design list */
.dg .checks > li { display: flex; gap: var(--sp-3); align-items: center; padding: var(--sp-3) var(--sp-1); border-bottom: 1px solid var(--hair); }
.dg .lines > li { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 10px 0; border-bottom: 1px solid var(--hair); } /* ds-ok: design lines */
.dg .rows > li:last-child, .dg .list > li:last-child, .dg .checks > li:last-child, .dg .lines > li:last-child { border-bottom: 0; }
.dg .lines > li:last-child { font-weight: 700; }
.dg .who { flex: 1; min-width: 0; }
.dg .who b { display: block; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dg .who small { color: var(--muted); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dg .who.wrap { max-width: none; margin: 0; padding: 0; overflow-x: visible; } /* not the hub page .wrap */
.dg .wrap b, .dg .wrap small, .dg .rows .who small { white-space: normal; }
.dg .src { width: 32px; height: 32px; border-radius: var(--r-sm); display: grid; place-items: center; flex: none; background: var(--well); color: var(--muted); } /* ds-ok: design icon tile 32 */
.dg .src.on { background: var(--primary-soft); color: var(--primary-text); }
.dg .track { display: grid; grid-template-columns: repeat(var(--n), 1fr); gap: 6px; margin: 6px 0 var(--sp-1); } /* ds-ok: design track */
.dg .track > div { display: grid; gap: 6px; font-size: var(--fs-cap); color: var(--muted); text-align: center; } /* ds-ok: design track */
.dg .track > div i { height: 6px; border-radius: var(--r-pill); background: var(--hair-2); } /* ds-ok: design track bar */
.dg .track > div.on i { background: var(--primary); }
.dg .track > div.now i { background: var(--now); animation: dg-pulse 1.6s ease-in-out infinite; } /* ds-ok: design "now" pulse */
.dg .track > div.now { color: var(--ink); font-weight: 600; }
@keyframes dg-pulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .dg .track > div.now i { animation: none; } }
.dg .demo { display: grid; gap: 18px; margin-top: 18px; } /* ds-ok: design demo */
.dg .demo__info { display: grid; gap: var(--sp-3); min-width: 0; }
.dg .demo__info > b { font-size: var(--fs-title); }
.dg .demo__info p { margin: -6px 0 0; font-size: var(--fs-ui); } /* ds-ok: design demo text pull-up */
.dg .tile { min-width: 0; height: 150px; border-radius: var(--r-md); background: var(--ground-2); border: 1px solid var(--hair); position: relative; overflow: hidden; padding: var(--sp-3); display: grid; align-content: start; gap: 6px; } /* ds-ok: design demo tile */
.dg .tile i { display: block; height: 7px; border-radius: var(--r-xs); background: var(--hair-2); } /* ds-ok: design tile line */
.dg .tile i.h { height: 12px; width: 62%; background: var(--primary); opacity: .75; } /* ds-ok: design tile heading */
.dg .tile i.w5 { width: 50%; } .dg .tile i.w7 { width: 72%; }
.dg .tile .blocks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-top: var(--sp-1); } /* ds-ok: design tile blocks */
.dg .tile .blocks span { height: 22px; border-radius: var(--r-xs); background: var(--card-solid); border: 1px solid var(--hair); } /* ds-ok: design tile block */
.dg .kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-3) 18px; margin: 0; padding: 0; font-size: inherit; } /* ds-ok: design kv */
.dg .demo .kv { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.dg .kv div { min-width: 0; }
.dg .kv dt { font-family: inherit; font-size: var(--fs-cap); color: var(--muted); align-self: auto; }
.dg .kv dd { display: block; gap: normal; align-items: normal; margin: 2px 0 0; font-weight: 600; overflow-wrap: anywhere; } /* ds-ok: design kv gap */
.dg .kv dd .btn.icon { width: 26px; height: 26px; vertical-align: middle; margin-left: var(--sp-1); box-shadow: none; } /* ds-ok: design copy button */
.dg .btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.dg .box { width: 20px; height: 20px; border-radius: var(--r-xs); border: 1.6px solid var(--hair-2); background: var(--card-solid); display: grid; place-items: center; flex: none; padding: 0; color: var(--card-solid); } /* ds-ok: design check box */
.dg .box[aria-checked="true"] { background: var(--primary); border-color: var(--primary); }
.dg .box .ic { width: 13px; height: 13px; stroke-width: 2.6; } /* ds-ok: design check glyph */
.dg .checks li.done .who b { text-decoration: line-through; color: var(--muted); }
.dg .proxy { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 6px; } /* ds-ok: design proxy row */
.dg .msgbox { padding: 14px 16px; border-radius: var(--r-md); background: var(--well); line-height: 1.55; } /* ds-ok: design msgbox */
.dg .proxy small { display: inline-flex; align-items: center; gap: var(--sp-1); color: var(--primary-text); font-weight: 600; }
.dg .paylist > li { cursor: pointer; margin-inline: -10px; padding-inline: 10px; border-radius: var(--r-ctl); transition: background-color var(--t-fast); } /* ds-ok: design pay row inset */
.dg .paylist > li:hover { background: var(--side-hover); }
.dg .paylist > li[aria-selected="true"] { background: var(--primary-soft); }
.dg .paylist > li > .num { font-family: var(--display); font-weight: 650; }
.dg .qrwrap { display: grid; place-items: center; padding: 6px 0 18px; } /* ds-ok: design qr frame */
.dg .qr { width: 184px; aspect-ratio: 1; padding: var(--sp-3); border-radius: var(--r-md); background: oklch(100% 0 0); border: 1px solid var(--hair); } /* ds-ok: design QR stays white in dark */
.dg .qr img { display: block; width: 100%; height: 100%; object-fit: contain; }
.dg .pay-ok { width: 100%; margin-top: var(--sp-4); }
.dg .tbl td small { color: var(--muted); display: block; }
.dg .tbl td.r, .dg .tbl th.r { text-align: right; }
.dg .chiprow { display: flex; gap: 6px; flex-wrap: wrap; margin-top: var(--sp-1); } /* ds-ok: design chip row */
.dg .card:not(.flush) .tblwrap { margin-inline: calc(var(--pad) * -1); }
/* design .tbl-wrap @container: a table narrower than 640px (a drawer, a phone) shows each row as a block, first cell on its own line */
:is(.dg, .dgp) .tblwrap { container-type: inline-size; border: 0; border-radius: 0; }
@container (min-width: 641px) { :is(.dg, .dgp) .tblwrap td b, :is(.dg, .dgp) .tblwrap td small, :is(.dg, .dgp) .tblwrap td .pill { white-space: nowrap; } }
@container (max-width: 640px) {
  :is(.dg, .dgp) .tblwrap .tbl, :is(.dg, .dgp) .tblwrap .tbl > tbody, :is(.dg, .dgp) .tblwrap .tbl > tbody > tr, :is(.dg, .dgp) .tblwrap .tbl > tbody > tr > td { display: block; }
  :is(.dg, .dgp) .tblwrap .tbl > thead { display: none; }
  :is(.dg, .dgp) .tblwrap .tbl > tbody > tr { display: grid; grid-template-columns: minmax(0, 1fr) fit-content(40%); gap: var(--sp-2) var(--sp-4); padding: 14px var(--pad, 12px); border-bottom: 1px solid var(--hair); } /* ds-ok: #161 design table row as a block */
  :is(.dg, .dgp) .tblwrap .tbl > tbody > tr:last-child { border-bottom: 0; }
  :is(.dg, .dgp) .tblwrap .tbl > tbody > tr > td { padding: 0; border: 0; }
  :is(.dg, .dgp) .tblwrap .tbl > tbody > tr > td:first-child { grid-column: 1 / -1; }
  :is(.dg, .dgp) .tblwrap .tbl td.r { text-align: left; }
  :is(.dg, .dgp) .tblwrap .tbl td.hide-sm { display: none; }
}
@container (min-width: 641px) and (max-width: 940px) { :is(.dg, .dgp) .tblwrap .hide-md { display: none; } }
.dg .empty { color: var(--muted); padding: var(--sp-3) 2px; } /* ds-ok: design row inset 2px */
@media (max-width: 1180px) { .dg .g-side { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .dg .demo .kv { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dgs { position: fixed; inset: 0; z-index: var(--z-overlay); background: var(--backdrop); backdrop-filter: blur(var(--backdrop-blur)); -webkit-backdrop-filter: blur(var(--backdrop-blur)); }
.dgp { position: fixed; z-index: var(--z-modal); top: 0; right: 0; bottom: 0; width: min(480px, 100vw); background: var(--card-solid); border-left: 1px solid var(--hair); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; font-size: var(--fs-base); line-height: 1.5; } /* ds-ok: design panel width */
.dgp__head { display: flex; align-items: center; gap: var(--sp-3); padding: calc(16px + env(safe-area-inset-top, 0px)) 20px 16px; border-bottom: 1px solid var(--hair); } /* ds-ok: design panel head */
.dgp .dgp__title { flex: 1; font: 650 var(--fs-xl)/1.2 var(--display); letter-spacing: normal; margin: 0; }
.dgp__body { flex: 1; overflow-y: auto; padding: 20px; display: grid; align-content: start; gap: 18px; } /* ds-ok: design panel body */
.dgp__actions { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 20px calc(16px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--hair); } /* ds-ok: design panel actions */
.dgp h3 { margin: 0 0 var(--sp-2); font: 600 var(--fs-cap) var(--sans); color: var(--faint); text-transform: uppercase; letter-spacing: .06em; } /* ds-ok: design panel section label */
.dgp__head .btn.sm svg.ic:not(.ic-sm) { width: var(--ic-lg); height: var(--ic-lg); } /* drawing: close glyph 18 in the 32px button */
.dgp__sum { display: flex; align-items: center; gap: var(--sp-3); }
.dg .avatar.lg { width: 48px; height: 48px; font: 600 var(--fs-title)/1 var(--sans); border-radius: 50%; display: grid; place-items: center; flex: none; background: var(--well); color: var(--ink); border: 1px solid var(--hair); } /* ds-ok: design avatar lg */
.dg .field { display: grid; gap: 6px; font-weight: 550; font-size: var(--fs-ui); min-width: 0; } /* ds-ok: design field gap */
.dg .field textarea { min-height: 84px; padding: 10px 12px; resize: none; font-weight: 400; font-size: var(--fs-base); } /* ds-ok: design textarea */
.dg .field small { color: var(--muted); font-weight: 400; }
.dg .btn.attach { justify-self: start; }
.dg .pnote { margin: 0; font-size: var(--fs-ui); }
.dg .qrnote { margin-top: var(--sp-4); }
.dg .qrbtns { margin-top: 10px; } /* ds-ok: design qr buttons gap */
.dg .docnote { margin-top: var(--sp-4); }
/* one-tap link page /l/{code} (port of sanh-digotech.html .solo, #133): no app chrome, no login; the body already paints the ground + glow */
.dg.solo { min-height: 100vh; display: grid; place-items: center; padding: 32px var(--sp-4); box-sizing: border-box; } /* ds-ok: design solo padding */
.dg .solo__box { width: min(460px, 100%); display: grid; gap: 18px; } /* ds-ok: design solo box */
.dg .solo__brand { display: flex; align-items: center; justify-content: center; gap: 10px; color: var(--logo); font: 800 21px/1 var(--display); letter-spacing: .01em; text-transform: uppercase; } /* ds-ok: design solo brand */
.dg .solo__brand svg { width: 36px; height: 36px; } /* ds-ok: design solo logo */
.dg .solo__lang { display: flex; justify-content: center; }
.dg.solo .card { display: grid; gap: var(--sp-4); padding: 24px; } /* ds-ok: design solo card */
.dg.solo h1 { margin: 0; font: 650 var(--fs-h2)/1.2 var(--display); letter-spacing: normal; }
.dg.solo .card > p { margin: 0; }
.dg .solo__state { display: grid; justify-items: center; text-align: center; gap: 10px; } /* ds-ok: design solo state */
.dg .solo__state .src { width: 48px; height: 48px; } /* ds-ok: design solo state icon */
.dg .solo__alt { margin: 0; text-align: center; color: var(--muted); font-size: var(--fs-ui); }
.dg .solo__alt a { color: var(--primary-text); font-weight: 600; }
.dg .panel__sum { display: flex; align-items: center; gap: var(--sp-3); }
.dg.solo .subnote .ic { vertical-align: baseline; }
.dg.solo .subnote { display: block; min-height: 0; margin: 6px 0 0; font-family: inherit; font-size: var(--fs-sm); color: var(--muted); } /* ds-ok: design subnote */
.dg .seg { position: relative; display: inline-flex; padding: 3px; gap: 2px; background: var(--well); border-radius: var(--r-ctl); max-width: 100%; overflow-x: auto; } /* ds-ok: design seg */
.dg .seg__pill { position: absolute; left: 0; top: 3px; bottom: 3px; width: 0; border-radius: var(--r-sm); background: var(--night); box-shadow: var(--shadow); pointer-events: none; } /* ds-ok: design seg pill */
.dg .seg button { position: relative; z-index: 1; border: 0; background: transparent; padding: 6px 12px; border-radius: var(--r-sm); color: var(--muted); font: 550 var(--fs-sm) var(--sans); line-height: 1.5; white-space: nowrap; cursor: pointer; transition: color .25s; } /* ds-ok: design seg button */
.dg .seg button[aria-pressed="true"] { color: var(--night-ink); }
.dg .seg button .badge { height: 18px; min-width: 18px; margin-left: 4px; padding: 0 5px; border: 0; border-radius: var(--r-pill); display: inline-grid; place-items: center; font: 600 var(--fs-2xs)/1 var(--sans); background: var(--primary-soft); color: var(--primary-text); } /* ds-ok: design seg badge (.badge + .seg button .badge) */
.dg .nowrap { white-space: nowrap; flex: none; }
.dg .seg.small button { padding: 4px 9px; font-size: var(--fs-cap); } /* ds-ok: design seg small */
.dg .row-actions { display: flex; gap: 8px; flex-wrap: wrap; } /* ds-ok: design row-actions */
/* ── Nhắn Digotech · Hướng dẫn (sanh-digotech.html V.support / openReq / openReqDetail / V.help) ── */
.dg .tabs { position: relative; margin-bottom: var(--sp-4); }
.dg .tabs button { font-size: var(--fs-base); transition: color .25s; } /* ds-ok: design tab colour fade */
.dg .tabs button[aria-selected="true"]::after { display: none; } /* the drawing's line slides (.tabs__line) */
.dg .tabs__line { position: absolute; left: 0; bottom: -1px; height: 2px; width: 0; border-radius: var(--r-xs); background: var(--primary); } /* ds-ok: design tab line 2px */
.dg .toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: var(--sp-4); } /* ds-ok: design toolbar gap */
.dg .avatar { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; flex: none; font: 600 var(--fs-cap)/1 var(--sans); background: var(--well); color: var(--ink); border: 1px solid var(--hair); } /* ds-ok: design avatar 34 */
.dg .chatwrap { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--sp-4); height: max(520px, calc(100vh - 240px)); } /* ds-ok: design chat layout */
.dg .chatwrap > .card.chat { padding: 0; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.dg .chatwrap > .stack { align-content: start; }
.dg .th-head { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) 14px; border-bottom: 1px solid var(--hair); } /* ds-ok: design thread head */
.dg .th-head .who { min-width: 90px; } /* ds-ok: design thread head */
.dg .th-head .who b { font-size: var(--fs-title); }
.dg .th-body { flex: 1; overflow-y: auto; padding: 18px; display: flex; flex-direction: column; gap: var(--sp-3); } /* ds-ok: design thread body */
.dg .th-body.flat { padding: 0; }
.dg .msg { display: block; gap: normal; align-items: normal; max-width: min(560px, 82%); padding: 11px 14px; border-radius: var(--r-md); background: var(--well); align-self: flex-start; overflow-wrap: anywhere; white-space: pre-wrap; } /* ds-ok: design bubble */
.dg .msg.me { background: var(--night); color: var(--night-ink); align-self: flex-end; border-bottom-right-radius: 6px; } /* ds-ok: design bubble tail */
.dg .msg.them { border-bottom-left-radius: 6px; } /* ds-ok: design bubble tail */
.dg .msg small { display: block; font-size: var(--fs-cap); opacity: .7; margin-top: var(--sp-1); white-space: normal; }
.dg .day { align-self: center; font: 500 var(--fs-2xs) var(--mono); color: var(--faint); padding: var(--sp-1) 10px; border-radius: var(--r-pill); background: var(--well); } /* ds-ok: design day chip */
.dg .composer { border-top: 1px solid var(--hair); padding: var(--sp-3) 14px 14px; display: grid; gap: 10px; position: relative; } /* ds-ok: design composer */
.dg .composer textarea { width: 100%; border: 0; outline: 0; background: transparent; resize: none; min-height: 56px; max-height: 160px; line-height: 1.5; padding: 2px; box-shadow: none; color: var(--ink); font: inherit; } /* ds-ok: design composer box */
.dg .cmp-bar { display: flex; align-items: center; gap: var(--sp-1); }
.dg .cmp-bar .hint { color: var(--faint); font-size: var(--fs-cap); margin-left: 6px; margin-right: auto; } /* ds-ok: design hint gap */
.dg .quick { display: grid; gap: var(--sp-2); }
.dg .quick .btn { justify-content: flex-start; }
.dg .hours { margin: 0; font-size: var(--fs-ui); }
.dg .spnote { margin-top: var(--sp-4); }
.dg .reqmeta { margin: 0; display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.dg .acc { display: grid; gap: 10px; border: 0; border-radius: 0; overflow: visible; } /* ds-ok: design acc gap */
.dg .acc__item { border-radius: var(--r-lg); background: var(--card); border: 1px solid var(--edge); box-shadow: var(--shadow); overflow: hidden; }
.dg .acc__btn { width: 100%; display: flex; align-items: center; gap: 14px; padding: var(--sp-4) 18px; border: 0; background: transparent; text-align: left; color: inherit; font: inherit; cursor: pointer; } /* ds-ok: design acc head */
.dg .acc__btn .who b { font-size: var(--fs-title); }
.dg .acc__chev { color: var(--muted); transition: transform .4s cubic-bezier(.22, 1, .36, 1); } /* ds-ok: design chevron ease */
.dg .acc__item.open .acc__chev { transform: rotate(180deg); }
.dg .acc__body { overflow: hidden; height: 0; }
.dg .acc__item.open .acc__body { height: auto; }
.dg .acc__inner { padding: var(--sp-1) 18px 18px; display: grid; gap: 14px; } /* ds-ok: design acc body */
.dg .acc__inner p { margin: 0; }
@media (max-width: 1100px) { .dg .chatwrap { grid-template-columns: minmax(0, 1fr); } .dg .chatwrap > .stack { display: none; } }
@media (max-width: 640px) { .dg .chatwrap { height: calc(100vh - 220px); min-height: 480px; } } /* ds-ok: design chat mobile */
/* ── Hồ sơ & bảo mật + Người dùng & quyền (sanh-digotech.html V.account / V.team, #161) ── */
.dg .g-2 { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); } /* ds-ok: design main/side split */
.dg .g-2e { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 960px) { .dg .g-2, .dg .g-2e { grid-template-columns: minmax(0, 1fr); } } /* ds-ok: design breakpoint */
.dg .avatar { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; flex: none; font: 600 var(--fs-cap)/1 var(--sans); background: var(--well); color: var(--ink); border: 1px solid var(--hair); } /* ds-ok: design avatar 34 */
.dg .fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; } /* ds-ok: design fields */
.dg .field { font-size: var(--fs-ui); }
.dg .field .input.code { font: 400 var(--fs-sm)/1.55 var(--mono); }
.dg .switch { width: 38px; height: 22px; border-radius: var(--r-pill); border: 0; padding: 0; font: inherit; color: inherit; background: var(--hair-2); position: relative; flex: none; cursor: pointer; transition: background-color .25s; } /* ds-ok: design switch 38×22 */
.dg .switch i { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--card-solid); box-shadow: 0 1px 3px oklch(0% 0 0 / .25); transition: transform .28s cubic-bezier(.22,1,.36,1); } /* ds-ok: design switch knob */
.dg .switch[aria-checked="true"] { background: var(--primary); }
.dg .switch[aria-checked="true"] i { transform: translateX(16px); } /* ds-ok: design knob travel */
.dg .tgs { display: flex; flex-wrap: wrap; gap: 6px; } /* ds-ok: design tgs */
.dg .tg { border: 1px solid var(--hair-2); background: var(--card-solid); padding: 6px 12px; border-radius: var(--r-sm); font: 550 var(--fs-sm) var(--sans); color: var(--muted); cursor: pointer; transition: background-color .2s, color .2s, border-color .2s; } /* ds-ok: design tg */
.dg .tg[aria-pressed="true"] { background: var(--primary-soft); color: var(--primary-text); border-color: var(--primary); }
.dg .subnote { display: block; min-height: 0; margin: 6px 0 0; font-family: inherit; color: var(--muted); font-size: var(--fs-sm); } /* ds-ok: design subnote (p in the drawing) */
.dg .aclang { margin-top: 14px; } /* ds-ok: design inline margin */
.dg .aclang .solo__lang { display: block; }
.dg .aclang h3 { margin: 1em 0; font: 700 1.17em/1.5 var(--sans); letter-spacing: normal; } /* ds-ok: drawing leaves this h3 at the browser default size/margins */
.dg .acbill { margin-top: var(--sp-3); }
.dg .rows + .notice { margin-top: 14px; } /* ds-ok: design notice margin */
.dg .dsel .trg > svg.ic { color: var(--muted); }
.dg .rows .dsel.auto { min-width: 0; }
@media (max-width: 640px) { .dg .team > li { flex-wrap: wrap; } .dg .team > li > .who { flex-basis: calc(100% - 52px); } } /* ds-ok: design team row wrap */
/* phone: filter segs wrap instead of scrolling; a row with a trailing button drops it under the text (sanh-digotech / cms-digoweb drawings, DN 10-22) */
@media (max-width: 640px) {
  .dg .seg:not(.period):not(#langSeg) { flex-wrap: wrap; overflow: visible; }
  .dg .rows > li:has(> .btn) { flex-wrap: wrap; row-gap: 8px; } /* ds-ok: design row wrap */
  .dg .rows > li:has(> .btn) > .who { flex-basis: calc(100% - 48px); } /* ds-ok: design avatar 34 + gap 14 */
  .dg .rows > li:has(> .btn) > .who + * { margin-left: 48px; } /* ds-ok: design avatar 34 + gap 14 */
  .dg .rows > li:has(> .btn) > .btn { margin-left: auto; }
}
.dg .cmp-bar .btn.icon .ic:not(.ic-sm) { width: var(--ic-lg); height: var(--ic-lg); } /* drawing: 18px glyph in the 32px button */
.dg .btn.sm svg.ic:not(.ic-sm) { width: var(--ic-lg); height: var(--ic-lg); } /* drawing: only .ic-sm shrinks a glyph; a small button keeps the 18px .ic */
/* ── top screens: Tổng quan · Web đang làm · Thanh toán · Hợp đồng (sanh-digotech.html V.overview / V.projects / V.pay / V.docs) ── */
.dg .plain { margin: 0; }
/* ── Web đang chạy (sanh-digotech.html V.sites · openRenew / openUpgrade / openBackups / openBrief) ── */
.dg .plat { flex: none; width: 20px; height: 20px; color: var(--muted); } /* ds-ok: design platform mark 20 */
.dg .site-h { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.dg .site-h .plat { width: 28px; height: 28px; gap: normal; align-items: normal; } /* ds-ok: design card platform mark 28; drops fabric .tbl .plat flex */
.dg .wmeters { display: grid; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.dg .mtr { display: grid; gap: 6px; } /* ds-ok: design meter gap */
.dg .mtr div { display: flex; justify-content: space-between; font-size: var(--fs-sm); color: var(--muted); }
.dg .mtr b { color: var(--ink); font-family: var(--mono); font-weight: 500; }
.dg .mtr > div { align-items: center; }
.dg .mtr .mtr__end { display: flex; align-items: center; gap: 10px; } /* ds-ok: design meter end gap */
.dg .meter { height: 6px; border-radius: var(--r-pill); background: var(--hair-2); overflow: hidden; min-width: 80px; } /* ds-ok: design meter */
.dg .meter i { display: block; height: 100%; background: var(--primary); border-radius: inherit; transform-origin: left; }
.dg .meter.hi i { background: var(--deep); }
.dg .kv dd.dd-act { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
/* v16 (#211): webs are a table — a row opens the sheet; the end date shows a hover card (sanh-digotech.html siteRow · .exp · .go · .hvpop) */
.dg table.sites { display: table; } /* fabric .sites is the old card grid */
.dg .tbl tbody tr[data-open] { cursor: pointer; }
.dg .tbl .go { width: 30px; height: 30px; border-radius: var(--r-sm); display: inline-grid; place-items: center; color: var(--muted); } /* ds-ok: design row chevron 30 */
.dg .tbl tr:hover .go { background: var(--card-solid); color: var(--ink); box-shadow: var(--shadow); }
.dg .exp { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; border-bottom: 1px dashed var(--hair-2); }
.dg .exp.soon { color: var(--primary-text); font-weight: 600; }
.dg .exp.late { color: var(--off); font-weight: 600; }
.dg [data-hv]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: var(--r-sm); } /* ds-ok: focus ring offset, same as fabric.css */
.dg .notice.ws-note { margin-bottom: var(--sp-4); } /* design --gap 16 */
.dg .notice:has(> .btn) { align-items: center; padding-block: var(--sp-2); }
.dg .notice.ws-note > .btn, .dg .notice.ws-note > small { margin-left: auto; }
.hvpop.dg { position: fixed; z-index: 80; min-width: 240px; max-width: min(340px, calc(100vw - 24px)); padding: 10px 12px; border-radius: var(--r-md); background: var(--card-solid); border: 1px solid var(--hair); box-shadow: var(--shadow-lg); font-size: var(--fs-sm); pointer-events: none; } /* ds-ok: design hover card */
.dg .hv-kv { display: grid; gap: 6px; margin: 0; } /* ds-ok: design hover card rows */
.dg .hv-kv div { display: flex; justify-content: space-between; gap: 16px; } /* ds-ok: design hover card gap */
.dg .hv-kv dt { color: var(--muted); }
.dg .hv-kv dd { margin: 0; font-weight: 600; text-align: right; overflow-wrap: anywhere; }
.dgp__actions.one-row { flex-wrap: nowrap; gap: 8px; } /* ds-ok: design one-row actions */
.dgp__actions.one-row .btn { flex: 1 1 auto; min-width: 0; padding: 0 10px; gap: 6px; } /* ds-ok: design one-row button */
.dg .up-sub { margin: 0 0 10px; font-size: var(--fs-sm); } /* ds-ok: design uptime sub line */
.dg .notice.off { background: transparent; color: var(--off); box-shadow: inset 0 0 0 1px currentColor; } /* ds-ok: same ring as fabric .pill.bad — a destructive warning reads like .btn.danger */
.dg .pnote-sm { margin: 0; font-size: var(--fs-sm); }
/* ── Web: Gói & tên miền · tạm ngưng (sanh-digotech.html V['w/plan'] / V['w/locked'] · openDomain / openInvite) ── */
.dg .avatar.sm { width: 28px; height: 28px; font-size: var(--fs-2xs); } /* ds-ok: design avatar sm 28 */
.dg .domrows { margin-top: var(--sp-2); }
.dg .domst { margin: 0; display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.dg .wlask { margin-top: 14px; } /* ds-ok: design inline margin */
/* ── sign-in screens login.html · reset.html (sanh-digotech.html authHtml, .field.bad L1003-1004) ── */
.dg .field.bad .input { border-color: var(--off); }
.dg .field.bad small { color: var(--off); }
.dg .thumb { aspect-ratio: 4 / 3; border-radius: var(--r-md); background: linear-gradient(135deg, var(--primary-soft), var(--ground-2)); border: 1px solid var(--hair); display: grid; place-items: center; color: var(--primary-text); position: relative; overflow: hidden; }
.dg .thumb.big { aspect-ratio: 16 / 9; gap: 12px; } /* ds-ok: the drawing's .big (KPI figure row) also lends the thumb its 12px gap */
.dg .thumb .ic { width: 30px; height: 30px; opacity: .8; } /* ds-ok: design thumb glyph */
.dg .thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: var(--card-solid); }
.dg .qr svg { display: block; width: 100%; height: 100%; }
.dg .qr path { fill: oklch(24% .03 160); } /* ds-ok: design QR module colour (#10241b), stays dark on the white card in both themes */
/* status: 90-day uptime bar (drawing .upbar/.axis) */
.dg .upbar { position: relative; display: grid; grid-template-columns: repeat(90, minmax(0, 1fr)); gap: 2px; height: 30px; } /* ds-ok: design 90-day bar */
.dg .upbar i { border-radius: 2px; background: var(--primary); } /* ds-ok: design bar tick */
.dg .upbar i.part { opacity: .55; }
.dg .upbar i.miss { background: var(--off); }
.dg .upbar i.none { background: var(--hair-2); }
.dg .upbar .tip { position: absolute; z-index: 5; pointer-events: none; padding: 8px 10px; border-radius: var(--r-sm); background: var(--night); color: var(--night-ink); font-size: var(--fs-cap); white-space: nowrap; box-shadow: var(--shadow); transform: translate(-50%, -112%); } /* ds-ok: design bar tooltip */
.dg .upbar .tip.below { transform: translate(-50%, 14px); } /* ds-ok: design tooltip under the point */
.dg .axis { display: flex; justify-content: space-between; margin-top: 8px; font-size: var(--fs-cap); color: var(--faint); font-variant-numeric: tabular-nums; } /* ds-ok: design axis gap; design --fs-xs 12 = fabric --fs-cap */

.dg .next__item p { font-size: var(--fs-ui); }
