/* ============================================================
   MARKETING — app shell (MKT_SHELL_V1, 2026-08-06)
   Concept 1 in the ANALYTICS theme, operator-approved via artifact:
   left icon rail on navy-900 with the 2px gold edge, cream ground,
   gold hover language, navy-.85 active states. Tokens are the LIVE
   analytics.css values (its --navy/--gold/--cream/--hairline), not
   approximations. All class names kept — marketing.js is untouched;
   the rail buttons are still .mkt-tab[data-mt] driven by mktTab().
   Rollback: /root/archive/marketing-preshell-20260806/ or git 19ffedf.
============================================================ */
:root {
  --mkt-navy: #0f1f3d;        /* analytics --navy (navy-900) */
  --mkt-gold: #a07a22;        /* analytics --gold (gold-600) */
  --mkt-cream: #faf7f0;       /* analytics body ground */
  --mkt-hairline: #e8e0cf;    /* analytics card border */
  --mkt-gold-tint: rgba(160,122,34,0.12);  /* gold-100: the hover tint */
}

body { background: var(--mkt-cream); }
#mkt-app { display: flex; min-height: 100vh; align-items: stretch; }

/* ============ THE RAIL ============ */
.mkt-rail {
  flex: 0 0 88px; width: 88px;
  background: var(--mkt-navy); border-right: 2px solid var(--mkt-gold);
  position: sticky; top: 0; height: 100vh; z-index: 50;
  display: flex; flex-direction: column; align-items: center;
  padding: 16px 0 14px; gap: 5px;
}
/* Operator 2026-08-06: the logo mark rendered WHITE (CSS invert) on the navy, inside a
   white ring — the flat white disc "didn't look good". */
.mkt-raillogo {
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1.5px solid rgba(255,255,255,.55); border-radius: 50%;
  margin-bottom: 12px; user-select: none; overflow: hidden;
}
.mkt-raillogo img { width: 28px; height: 28px; object-fit: contain; display: block; filter: brightness(0) invert(1); opacity: .95; }
/* The tab buttons keep their class + data-mt so mktTab() needs no change. */
.mkt-rail .mkt-tab {
  width: 68px; padding: 9px 0 7px; border: 1px solid transparent; border-radius: 10px;
  background: transparent; cursor: pointer; font-family: inherit;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  color: rgba(255,255,255,.60); font-size: 9.5px; font-weight: 600; letter-spacing: .02em;
  transition: background .15s ease, color .15s ease;
}
.mkt-rail .mkt-tab svg { width: 20px; height: 20px; flex: 0 0 auto; }
/* Hover = the analytics topbar icon-button hover: white out, navy ink. */
.mkt-rail .mkt-tab:hover { background: rgba(255,255,255,.95); color: var(--mkt-navy); }
.mkt-rail .mkt-tab.active {
  background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.4); color: #fff;
  box-shadow: inset 3px 0 0 var(--gold-500);
}
.mkt-railspacer { flex: 1; }
.mkt-rtool {
  width: 44px; height: 40px; border-radius: 10px; border: 1px solid transparent;
  background: transparent; color: rgba(255,255,255,.60); cursor: pointer;
  display: flex; align-items: center; justify-content: center; text-decoration: none;
  transition: background .15s ease, color .15s ease;
}
/* Breathing room between Dashboard and Logout (operator: they sat too close). */
.mkt-rtool + .mkt-rtool { margin-top: 10px; }
.mkt-rtool svg { width: 19px; height: 19px; }
.mkt-rtool:hover { background: rgba(255,255,255,.95); color: var(--mkt-navy); }
.mkt-rtool.out:hover { background: rgba(220,38,38,.92); color: #fff; }
/* MKT_I18N_V1 — the JP/EN toggle is the only rail tool with a text label instead of an
   icon, so it needs its own type sizing; the box, hover and spacing stay identical to
   the icon tools around it. Same button also appears in the mobile header (.mkt-htool). */
.mkt-rtool.mkt-langbtn { font-size: 12px; font-weight: 700; letter-spacing: .06em; font-family: inherit; }
.mkt-htool.mkt-langbtn { font-size: 11px; font-weight: 700; letter-spacing: .04em; font-family: inherit; }
/* MKT_I18N_V3 — /passwords/ is a separate page but loads this stylesheet and the same
   module, so its toggle is styled here beside the other two rather than inline there. */
.pw-tool.mkt-langbtn { font-size: 11px; font-weight: 700; letter-spacing: .04em; font-family: inherit; }

/* ============ CONTENT COLUMN ============ */
.mkt-content { flex: 1; min-width: 0; }
.mkt-head {
  position: sticky; top: 0; z-index: 40;
  background: var(--mkt-cream);
  display: flex; align-items: center; gap: 12px; padding: 11px 26px;
}
/* Operator 2026-08-06: the hard full-width underline replaced by the brand's fading gold
   hairline (the divider base.css already uses) — reads as a rule of gold, not a border. */
.mkt-head::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-600) 14%, var(--gold-500) 86%, transparent);
}
.mkt-head-tools { display: none; }
.mkt-htool {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid rgba(15,31,61,.25);
  background: #fff; color: var(--mkt-navy); cursor: pointer; text-decoration: none;
  display: flex; align-items: center; justify-content: center;
}
.mkt-htool svg { width: 16px; height: 16px; }
.mkt-htool:hover { border-color: var(--mkt-gold); }
.mkt-htool.out:hover { background: rgba(220,38,38,.92); color: #fff; border-color: transparent; }
.mkt-head .brand { font-family: var(--font-display); font-size: 19px; letter-spacing: .5px; color: var(--mkt-navy); }
.mkt-head .brand .accent { color: var(--mkt-gold); }
.mkt-head .spacer { flex: 1; }
.mkt-ava {
  width: 34px; height: 34px; border-radius: 50%; background: rgba(15,31,61,.85); color: #fff;
  font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,255,255,.4); user-select: none;
}
/* Operator 2026-08-06: the 1200px cap left dead space on both sides — data pages get the width. */
.mkt-wrap { max-width: none; padding: 22px 32px 60px; }

/* ============ COMPONENT RETHEME (same classes, analytics tokens) ============ */
.mkt-scope { display: flex; gap: 6px; margin-bottom: 18px; }
.mkt-scope button {
  padding: 7px 14px; border: 1px solid rgba(15,31,61,.2); background: #fff; border-radius: 8px;
  cursor: pointer; font-family: inherit; font-size: 13px; color: var(--gray-500);
}
.mkt-scope button.active { background: rgba(15,31,61,.85); color: #fff; border-color: rgba(255,255,255,.4); }
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px,1fr)); gap: 14px; margin-bottom: 26px; }
.kpi {
  background: #fff; border: 1px solid var(--mkt-hairline); border-radius: 12px; padding: 16px 18px;
  transition: border-color .2s ease;
}
.kpi:hover { border-color: var(--mkt-gold); }
.kpi .label { font-size: 12px; color: var(--gray-500); text-transform: uppercase; letter-spacing: .4px; margin-bottom: 6px; }
.kpi .value { font-size: 24px; font-weight: 700; color: var(--mkt-navy); }
.kpi .sub { font-size: 12px; color: var(--gray-400); margin-top: 3px; }
.kpi.leak .value { color: var(--gold-600); }
.card {
  background: #fff; border: 1px solid var(--mkt-hairline); border-radius: 12px; padding: 18px 20px;
  box-shadow: var(--shadow-sm); margin-bottom: 22px;
}
.card h3 { font-size: 14px; font-weight: 700; color: var(--mkt-navy); margin-bottom: 4px; }
.card .hint { font-size: 12px; color: var(--gray-400); margin-bottom: 16px; }
.bars { display: flex; align-items: flex-end; gap: 8px; height: 200px; padding-top: 20px; overflow-x: auto; }
.bar-col { flex: 1 0 42px; display: flex; flex-direction: column; align-items: center; height: 100%; justify-content: flex-end; }
.bar { width: 70%; background: var(--gold-500); border-radius: 4px 4px 0 0; position: relative; min-height: 2px; transition: height .3s; }
.bar.partial { background: repeating-linear-gradient(45deg, var(--gold-500), var(--gold-500) 6px, var(--gold-600) 6px, var(--gold-600) 12px); }
.bar-val { font-size: 11px; font-weight: 600; color: var(--mkt-navy); margin-bottom: 4px; }
.bar-lbl { font-size: 10px; color: var(--gray-400); margin-top: 6px; white-space: nowrap; }
.bar-sub { font-size: 9px; color: var(--gray-400); }
.pace-row { display: flex; gap: 10px; overflow-x: auto; }
.pace-cell { flex: 0 0 120px; border: 1px solid var(--mkt-hairline); border-radius: 10px; padding: 12px; background: var(--gray-50); }
.pace-cell .pm { font-size: 12px; font-weight: 600; color: var(--navy-700); }
.pace-cell .pb { font-size: 18px; font-weight: 700; color: var(--mkt-navy); margin: 4px 0; }
.pace-cell .pr { font-size: 11px; color: var(--gray-500); }
/* Tables: the analytics language — navy header, gold-100 row hover.
   MKT_TABLE_SCROLL_V1 (2026-08-06): natural width + container scroll at EVERY viewport,
   not just phones — at in-between window widths (e.g. ~900px) the members table's
   min-content exceeded the card and the navy header ran outside it. Same model as
   analytics MOBILE_TABLE_SCROLL_V1, promoted to a base rule. */
#crm-table, #mb-table, #lnk-table, #fc-table, #pr-table, #an-body .card { overflow-x: auto; }
table.mkt { width: auto; min-width: 100%; border-collapse: collapse; font-size: 13px; }
table.mkt th {
  text-align: left; padding: 9px 10px; background: var(--mkt-navy); color: #fff;
  font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .3px;
}
table.mkt td { padding: 9px 10px; border-bottom: 1px solid #f2ecdf; }
table.mkt tbody tr { transition: background-color .2s ease; }
table.mkt tbody tr:hover { background: var(--mkt-gold-tint); }
table.mkt td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.mkt tr.closed td { color: var(--gray-400); font-style: italic; }
.brand-tag { font-size: 10px; padding: 2px 7px; border-radius: 20px; background: var(--gold-100); color: var(--gold-600); border: 1px solid var(--gold-border); }
.brand-tag.cinqs { background: var(--info-bg); color: var(--info); border-color: var(--info); }
.brand-tag.sakimoto { background: var(--gray-100); color: var(--gray-700); border-color: var(--gray-200); }
.nat-row { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.nat-name { flex: 0 0 130px; font-size: 13px; color: var(--navy-700); }
.nat-bar { height: 16px; background: var(--navy-700); border-radius: 4px; }
.nat-count { font-size: 12px; color: var(--gray-500); font-variant-numeric: tabular-nums; }
.mkt-loading, .mkt-denied { text-align: center; padding: 80px 20px; color: var(--gray-500); }
.mkt-denied h2 { color: var(--mkt-navy); font-family: var(--font-display); margin-bottom: 10px; }
.placeholder { text-align: center; padding: 60px 20px; color: var(--gray-400); }
.placeholder .big { font-size: 40px; margin-bottom: 12px; }
.seg-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: 10px; margin-bottom: 14px; }
.seg-card { background:#fff; border:1px solid var(--mkt-hairline); border-radius:10px; padding:14px; cursor:pointer; transition: border-color .2s ease; }
.seg-card:hover { border-color: var(--mkt-gold); }
.seg-card.active { border-color: var(--mkt-navy); box-shadow: inset 0 0 0 1px var(--mkt-navy); }
.seg-card.gold .seg-v { color: var(--gold-600); }
.seg-v { font-size: 22px; font-weight: 700; color: var(--mkt-navy); }
.seg-l { font-size: 12px; color: var(--gray-500); margin-top: 2px; }
/* COUPON_VIEW_V1 - the coupon tag on booking rows. Operator, 2026-08-24, on the navy+gold pill:
   "those color drive too much attention for nothing" - and they were right. On New bookings a
   coupon is a rare footnote, not a status, so it is plain muted text sitting beside the booking id
   in the same register, NOT a filled badge. The filled badges on this page are reserved for issues.
   Colour is --gray-500 (4.76:1 on white). Gold text alone was asked about and measured at 3.96:1,
   under AA for 11px, and darkening it would have meant inventing a palette entry. */
.mkt-coupon-tag {
  display:inline; margin-left:6px; font-size:11px; font-weight:500;
  color: var(--gray-500); white-space:nowrap;
}
.chips { display:flex; flex-wrap:wrap; gap:6px; margin-bottom:16px; }
.chip {
  padding:5px 12px; border:1px solid rgba(15,31,61,.2); background:#fff; border-radius:20px;
  cursor:pointer; font-size:12px; font-family:inherit; color:var(--gray-700);
  box-shadow: 0 1px 3px rgba(15,31,61,.08); transition: all .2s ease;
}
.chip:hover { border-color: var(--mkt-gold); box-shadow: 0 2px 8px rgba(15,31,61,.12); }
.chip.active { background: rgba(15,31,61,.85); color:#fff; border-color: rgba(255,255,255,.4); box-shadow: 0 4px 14px rgba(15,31,61,.25); }
.crm-controls { display:flex; gap:14px; align-items:center; margin-bottom:14px; flex-wrap:wrap; }
.crm-controls input[type=text] {
  flex:1; min-width:200px; padding:9px 12px; border:1px solid rgba(15,31,61,.2); border-radius:8px;
  font-family:inherit; font-size:13px; background:#fff; transition: border-color .2s ease;
}
.crm-controls input[type=text]:hover { border-color: var(--mkt-gold); }
.crm-controls label { font-size:13px; color:var(--gray-700); display:flex; align-items:center; gap:6px; cursor:pointer; }
.crm-count { font-size:12px; color:var(--gray-500); margin-bottom:10px; }
.crm-note { font-size:12px; color:var(--gray-400); margin-top:10px; }
/* EMAIL_ORIGIN_V1 — inferred-from-domain values: visibly a guess, still filterable. */
.inf { color: var(--gray-400); font-style: italic; }
table.mkt .ok { color: var(--success-fg); font-weight:700; }
table.mkt .no { color: var(--gray-400); }
.cmp-recip { background: var(--gold-100); border:1px solid var(--gold-border); border-radius:8px; padding:10px 14px; font-size:13px; color:var(--mkt-navy); margin-bottom:14px; }
.cmp-recip b { font-size:15px; }
.cmp-recip .supp { color: var(--gray-500); font-size:12px; }
.cmp-field { margin-bottom:12px; }
.cmp-field label { display:block; font-size:12px; font-weight:600; color:var(--gray-500); text-transform:uppercase; letter-spacing:.3px; margin-bottom:5px; }
.cmp-field input, .cmp-field textarea { width:100%; padding:10px 12px; border:1px solid rgba(15,31,61,.2); border-radius:8px; font-family:inherit; font-size:13px; }
.cmp-field textarea { min-height:160px; resize:vertical; font-family:monospace; }
.cmp-preview-box { border:1px solid var(--mkt-hairline); border-radius:8px; overflow:hidden; }
.cmp-preview-box iframe { width:100%; height:340px; border:none; background:#fff; }
.cmp-actions { display:flex; gap:10px; margin-top:14px; flex-wrap:wrap; }
.cmp-btn { padding:10px 18px; border-radius:8px; border:none; font-family:inherit; font-size:13px; font-weight:600; cursor:pointer; }
.cmp-btn.test { background:var(--mkt-navy); color:#fff; }
.cmp-btn.send { background:var(--gold-500); color:#fff; }
.cmp-btn:disabled { background:var(--gray-200); color:var(--gray-400); cursor:not-allowed; }
.cmp-status { font-size:13px; margin-top:10px; }
.cmp-status.ok { color:var(--success); }
.cmp-status.err { color:var(--error); }

/* (CT_VIEWTABS removed 2026-08-06 — the metric cards themselves are the view switch,
   styled like the Analytics sub-tabs in index.html's CT_METRIC_STYLE_V1 block.) */

/* ============ MOBILE (MKT_MOBILE_V1, 2026-08-06) ============
   The analytics mobile model (MOBILE_TABLE_SCROLL_V1 / MOBILE_GUTTERS_V1 lineage), adapted
   to the app shell: rail becomes a bottom bar; cards stack 2-up; tables keep their NATURAL
   width and scroll inside their container instead of squeezing; gutters hand the screen to
   the data; toolbars and selects go full-width. */
@media (max-width: 768px) {
  #mkt-app { flex-direction: column; }
  .mkt-rail {
    position: fixed; bottom: 0; left: 0; right: 0; top: auto;
    width: 100%; height: 60px; flex: none;
    flex-direction: row; justify-content: space-around; align-items: center;
    padding: 3px 4px; gap: 0;
    border-right: none; border-top: 2px solid var(--mkt-gold);
    z-index: 60;
  }
  /* Dashboard + Logout move UP into the header (operator: the bar icons need the room);
     the six section tabs get the whole bar. */
  .mkt-raillogo, .mkt-railspacer, .mkt-rail .mkt-rtool { display: none; }
  .mkt-head-tools { display: flex; gap: 8px; align-items: center; }
  .mkt-rail .mkt-tab { flex: 1 1 0; min-width: 0; padding: 7px 4px 5px; font-size: 9.5px; gap: 3px; }
  .mkt-rail .mkt-tab svg { width: 20px; height: 20px; }
  .mkt-rail .mkt-tab.active { box-shadow: inset 0 3px 0 var(--gold-500); }
  .mkt-content { padding-bottom: 74px; }

  /* Gutters: give the width to the data (analytics MOBILE_GUTTERS_V1). */
  .mkt-head { padding: 8px 14px; }
  .mkt-head .brand { font-size: 16px; }
  .mkt-ava { width: 30px; height: 30px; font-size: 11px; }
  .mkt-wrap { padding: 14px 12px 60px; }
  .card { padding: 14px 12px; }

  /* Cards stack 2-up; numbers step down a size. ID-scoped ON PURPOSE: the .cts-* rules
     live in index.html's inline style block, which loads AFTER this file — equal
     specificity would lose on source order (the css-specificity-vs-source-order lesson). */
  /* Phones: 2-up via flex-basis (the cards row is flex now, not grid). */
  #ct-summary, #fb-summary { gap: 10px; }
  #ct-summary .cts-card, #fb-summary .cts-card { flex: 1 1 42%; max-width: none; padding: 12px 14px; }
  #ct-summary .cts-card .v, #fb-summary .cts-card .v { font-size: 19px; }
  .kpi .value { font-size: 20px; }
  .seg-v { font-size: 19px; }
  .nat-name { flex-basis: 90px; }
  .ops-subtabs { grid-template-columns: repeat(2, 1fr); gap: 8px; }

  /* Tables scroll at base now (MKT_TABLE_SCROLL_V1); phones just keep headers one line. */
  table.mkt th { white-space: nowrap; }

  /* Filters: search takes its own row; pill selects share rows at ~half width. */
  .crm-controls { gap: 8px; }
  .crm-controls input[type=text] { flex-basis: 100%; }
  #ct-chips { width: 100%; }
  #ct-chips .ct-sel { flex: 1 1 44%; max-width: none; }

  /* Analytics-section filter row: property select and date presets go full-width. */
  .ops-propsel { flex: 1 1 100%; min-width: 0; }
  .ops-daterow { margin-left: 0; width: 100%; }

  /* Contact-card overlay: use the screen, scroll its tables. Same id-scoping reason. */
  #mb-card .mbc-back { padding: 14px 8px; }
  #mb-card .mbc-b { padding: 14px 14px; overflow-x: auto; }
}

/* MKT_VIEWER_V1 - assistant viewer (body class set by marketing.js when the backend flags
   viewer:true). Admin-only rail tabs hide (Pricing granted 2026-08-12); the form tiles whose
   row views carry GUEST contact info (checkin/office) stay visible for their COUNTS but go
   inert - the backend refuses those row fetches for viewers anyway. Creator is allowed:
   follow-up contact with influencers is the assistant's job. */
body.mkt-viewer .mkt-tab[data-mt="contacts"],
body.mkt-viewer .mkt-tab[data-mt="links"],
body.mkt-viewer .mkt-tab[data-mt="vault"],
body.mkt-viewer .mkt-tab[data-mt="forecast"] { display: none; }
body.mkt-viewer .ops-ftile[data-ftype="checkin"],
body.mkt-viewer .ops-ftile[data-ftype="office"] { pointer-events: none; opacity: .55; }

/* ============================================================
   VAULT_V1 (2026-08-14) — Marketing → Passwords tab.
   Operator-approved mockup: artifact e6d51a93. Reuses the shell's
   existing language (.card / .kpi / .chip / table.mkt); only the
   password cell, the badges and the overlay are new.
============================================================ */
.pg-head { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.pg-head h1 {
  font-family: var(--font-display); font-size: 26px; font-weight: 700;
  color: var(--mkt-navy); margin: 0 0 4px; letter-spacing: .2px;
}
.pg-head .hint { font-size: 12.5px; color: var(--gray-500); margin: 0; max-width: 62ch; line-height: 1.55; }
.pg-head .spacer { flex: 1; }
.admin-pill {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 20px;
  background: var(--gold-100); color: var(--gold-600); border: 1px solid var(--gold-border);
}
.admin-pill svg { width: 13px; height: 13px; }

.btn-add {
  padding: 9px 16px; border-radius: 8px; border: none; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600;
  background: var(--mkt-navy); color: #fff;
  display: inline-flex; align-items: center; gap: 7px;
}
.btn-add svg { width: 14px; height: 14px; }
.btn-add:hover { background: var(--navy-700); }

.tbl-wrap { overflow-x: auto; background: #fff; border: 1px solid var(--mkt-hairline); border-radius: 12px; box-shadow: var(--shadow-sm); }
.tbl-wrap table.mkt td { padding: 10px 12px; vertical-align: middle; }
.tbl-wrap table.mkt tbody tr:last-child td { border-bottom: none; }

.acct-name { font-weight: 600; color: var(--mkt-navy); display: block; }
.acct-url { font-size: 11.5px; color: var(--gray-400); text-decoration: none; }
.acct-url:hover { color: var(--mkt-gold); text-decoration: underline; }
.vlt-login { font-size: 12.5px; color: var(--gray-700); white-space: nowrap; }

.pw-cell { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.pw-text {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 13px; color: var(--mkt-navy); letter-spacing: .5px;
  min-width: 132px; display: inline-block;
}
.pw-text.masked { letter-spacing: 2px; color: var(--gray-400); }
.pw-text.none { font-family: inherit; letter-spacing: 0; color: var(--gray-400); font-style: italic; font-size: 12px; }
.icon-btn {
  width: 28px; height: 28px; flex: 0 0 auto; border-radius: 7px;
  border: 1px solid rgba(15,31,61,.18); background: #fff; color: var(--gray-500);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s ease;
}
.icon-btn svg { width: 14px; height: 14px; }
.icon-btn:hover { border-color: var(--mkt-gold); color: var(--mkt-gold); }
.icon-btn.done { background: var(--success-fg); border-color: var(--success-fg); color: #fff; }

.vtag { font-size: 10px; padding: 2px 8px; border-radius: 20px; white-space: nowrap; font-weight: 600; display: inline-block; }
.vtag.yes { background: var(--gold-100); color: var(--gold-600); border: 1px solid var(--gold-border); }
.vtag.no  { background: var(--error-bg); color: var(--error-fg); border: 1px solid rgba(127,29,29,.2); }
.vtag.cat { background: var(--gray-100); color: var(--gray-700); border: 1px solid var(--gray-200); }
/* VAULT_2FA_TRISTATE_V1 — "not checked yet" reads as absent data, deliberately quieter than
   the red "None": missing information must not look like a finding. */
.vtag.unk { background: var(--gray-50); color: var(--gray-400); border: 1px dashed var(--gray-200); min-width: 22px; text-align: center; }

.vlt-date { font-variant-numeric: tabular-nums; font-size: 12.5px; color: var(--gray-500); white-space: nowrap; }
.vlt-date.stale { color: var(--warning-fg); background: var(--warning-bg); padding: 2px 7px; border-radius: 5px; }

.foot-note { font-size: 12px; color: var(--gray-400); margin-top: 14px; line-height: 1.6; max-width: 90ch; }
.foot-note b { color: var(--gray-500); }

/* overlay */
.vlt-modal {
  position: fixed; inset: 0; background: rgba(15,31,61,.45); z-index: 300;
  display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; overflow-y: auto;
}
.vlt-modal.hidden { display: none; }
.vlt-box {
  background: #fff; border: 1px solid var(--mkt-hairline); border-radius: 12px;
  padding: 22px 24px; width: 100%; max-width: 520px; box-shadow: 0 18px 50px rgba(15,31,61,.3);
}
.vlt-box h3 { font-size: 16px; font-weight: 700; color: var(--mkt-navy); margin: 0 0 16px; }
.vlt-box input[type=text], .vlt-box input[type=date], .vlt-box select {
  width: 100%; padding: 10px 12px; border: 1px solid rgba(15,31,61,.2);
  border-radius: 8px; font-family: inherit; font-size: 13px; background: #fff; color: var(--gray-700);
}
.vlt-box input[type=text]:focus-visible, .vlt-box input[type=date]:focus-visible, .vlt-box select:focus-visible {
  outline: 2px solid var(--gold-500); outline-offset: 1px; border-color: var(--mkt-gold);
}

@media (max-width: 768px) {
  .pg-head h1 { font-size: 22px; }
  .vlt-modal { padding: 16px 10px; }
}

/* VAULT_ASSIGN_GRANTS_TOOL_V1 — staff chips in the access picker. A dashed outline marks
   someone with NO standing access to the tool: ticking them in "only" mode grants it. */
.acc-staff label.nostand { border-style: dashed; }
.acc-staff .grants {
  font-size: 9px; font-weight: 700; letter-spacing: .03em; margin-left: 5px;
  background: var(--gold-500); color: #fff; border-radius: 10px; padding: 1px 5px;
}
.acc-staff label.on .grants { background: var(--gold-500); color: #fff; }


/* ============================================================
   VAULT_ACCESS_V1 — the "Who can see this" editor controls and the Access column.
   These live HERE, not in passwords/index.html's inline <style>, because BOTH surfaces
   (the Marketing tab and /passwords/) load this file and must render identically. Putting
   them on the page meant the Marketing tab rendered the same markup unstyled.
============================================================ */
  .acc-box { border: 1px solid var(--mkt-hairline); border-radius: 8px; padding: 12px; background: var(--gray-50); }
  .acc-staff { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
  .acc-staff label {
    display: inline-flex; align-items: center; gap: 5px; font-size: 12px; text-transform: none;
    letter-spacing: 0; font-weight: 400; color: var(--gray-700); background: #fff;
    border: 1px solid rgba(15,31,61,.18); border-radius: 20px; padding: 4px 10px; cursor: pointer; margin: 0;
  }
  .acc-staff label.on { background: rgba(15,31,61,.85); color: #fff; border-color: transparent; }
  .acc-staff input { margin: 0; cursor: pointer; }
  .acc-help { font-size: 12px; color: var(--gray-400); margin-top: 8px; line-height: 1.5; }
  .vtag.mode { background: var(--navy-700); color: #fff; border: none; }
  .vtag.mode.all { background: var(--gray-100); color: var(--gray-700); }
/* VAULT_MODAL_TIGHTEN_V1 (2026-08-15) — operator: "the text look big ... makes it long for
   no use". Cause: .hint is only styled under .card and .pg-head, and the editor overlay is
   neither, so hint text fell back to full body size. Scope it to the box and tighten the
   field rhythm; the explanatory hints themselves were deleted from the markup. */
.vlt-box .hint { font-size: 11.5px; color: var(--gray-400); margin: 4px 0 0; line-height: 1.45; }
.vlt-box .cmp-field { margin-bottom: 11px; }
.vlt-box .cmp-field label { font-size: 11px; }
.vlt-box .acc-box { padding: 10px; }
.vlt-box .acc-help { font-size: 11.5px; margin-top: 7px; }
.vlt-box .cmp-actions { margin-top: 4px; }

/* ============ OPS_BOOKINGS_PAGER_V1 (2026-08-24) ============
   Pager for Activity -> New bookings. Deliberately the same control language as .ops-preset
   (navy active, gold hover, 8px radius) so it reads as part of the existing filter row rather
   than a new widget. Tokens only - never a fourth palette. */
.nb-pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 14px;
}
.nb-pager-count { font-size: 12px; color: var(--gray-500, #6b7280); }
.nb-pager-btns { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.nb-page {
  padding: 6px 11px; min-width: 36px;
  border: 1px solid var(--mkt-hairline); border-radius: 8px; background: #fff;
  font-family: inherit; font-size: 13px; color: #374151; cursor: pointer;
}
.nb-page:hover:not(:disabled) { border-color: var(--mkt-gold); background: var(--mkt-gold-tint); }
.nb-page.active { background: var(--mkt-navy); color: #fff; border-color: var(--mkt-navy); }
.nb-page:disabled { opacity: .42; cursor: default; }
.nb-gap { color: #9ca3af; padding: 0 2px; }

/* The count line stacks above centred buttons on a phone - a space-between row puts them at
   opposite edges and the tap targets end up in the corners. */
@media (max-width: 640px) {
  .nb-pager { justify-content: center; }
  .nb-pager-count { width: 100%; text-align: center; }
}

/* ============ CAMPAIGNS_TAB_V1 (2026-08-24) ============
   Reuses the Contacts metric-card language (.cts-card) rather than inventing a second card
   style — these just don't switch a view, so they lose the pointer and the hover lift.
   `.unknown` greys the value: those cards print "—" because the metric has no mechanism behind
   it yet, and it must not look like a measured zero. */
.cts-card.static { cursor: default; }
.cts-card.static:hover {
  transform: none; box-shadow: 0 1px 2px rgba(16,24,40,.05); border-color: var(--mkt-hairline);
}
.cts-card.static.unknown .v { color: var(--gray-400, #9ca3af); font-weight: 600; }

.cg-ready-row {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 9px 0; border-top: 1px solid var(--mkt-hairline);
}
.cg-ready-row:first-of-type { border-top: none; }
.cg-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--mkt-gold); margin-top: 6px; flex: 0 0 8px;
}
.cg-ready-t { font-size: 13px; font-weight: 600; color: var(--mkt-navy); }
.cg-ready-d { font-size: 12px; color: var(--gray-500, #6b7280); margin-top: 1px; line-height: 1.45; }

/* ===== CAMPAIGN_COMPOSE_V2 (2026-08-25) — Campaigns sub-tabs, compose, template library.
   The V1 editor styles (.cgt-blk/.cgt-cols/.cgt-ta/.cgt-mini/.cgt-add/.cgt-slot/.cgt-h4) are
   REMOVED with the editor itself — templates are authored in a working session, not here.
   Own class prefix stays deliberate: borrowing .ops-subtab would enrol these nodes in every
   JS selector already targeting that class. */
.cg-subs { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; margin-bottom:16px; }
/* Values copied from the .ops-subtab block in marketing/index.html so this reads as the SAME
   component as the Activity sub-tabs, not an approximation of it. */
.cg-sub { background:#fff; border:1px solid #e8e0cf; border-radius:12px; padding:13px 16px;
  text-align:left; font-family:inherit; cursor:pointer; box-shadow:0 1px 2px rgba(16,24,40,.05);
  transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease, background .15s ease;
  display:block; width:100%; }
.cg-sub:hover { transform:translateY(-2px); box-shadow:0 4px 12px rgba(16,24,40,.10); border-color:#a07a22; }
.cg-sub-t { display:block; font-size:15px; font-weight:700; color:#0f1f3d; line-height:1.1; }
.cg-sub-s { display:block; font-size:11px; color:#6b7280; text-transform:uppercase;
  letter-spacing:.04em; font-weight:600; margin-top:5px; }
.cg-sub.on { background:#0f1f3d; border-color:#0f1f3d; box-shadow:0 4px 14px rgba(15,31,61,.28); }
.cg-sub.on .cg-sub-t { color:#fff; }
.cg-sub.on .cg-sub-s { color:#c9a227; }

/* Readiness: one compact line that opens. It used to be a full card and made the tab read as
   scaffolding; the blockers still matter, so they are one click away rather than gone. */
.cg-ready-strip { margin-bottom:14px; }
.cg-ready-det { background:#fff; border:1px solid var(--mkt-hairline); border-radius:10px; padding:0 14px; }
.cg-ready-det summary { cursor:pointer; padding:11px 0; display:flex; align-items:center; gap:8px;
  font-size:13px; color:var(--mkt-navy); list-style:revert; }
.cg-ready-h { font-weight:700; }
.cg-ready-n { background:var(--gold-100); border:1px solid var(--gold-border); color:var(--gold-600);
  border-radius:99px; font-size:11px; font-weight:700; padding:1px 8px; font-variant-numeric:tabular-nums; }
.cg-ready-det .cg-ready-row:last-child { padding-bottom:12px; }

/* Compose */
.cgc-row { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:16px; margin-bottom:4px; }
.cgc-f { min-width:0; }
.cgc-subj { background:var(--gray-50); border:1px solid var(--mkt-hairline); border-radius:8px;
  padding:9px 12px; margin:14px 0; font-size:14px; color:var(--mkt-navy); }
.cgc-subj-l { font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:var(--gray-500); margin-right:10px; }
.cgc-meta { font-size:12px; color:var(--gray-500); margin-top:8px; font-variant-numeric:tabular-nums; }
/* The send button says what it is about to do, and its reason sits NEXT TO it — a title
   tooltip does not exist on touch, which is half the usage of this page. */
.cgc-send { display:block; width:100%; margin-top:16px; padding:14px 20px; border-radius:8px;
  background:var(--mkt-navy); color:#fff; border:1px solid var(--mkt-navy); font-family:inherit;
  font-size:15px; font-weight:700; cursor:pointer; }
.cgc-send:disabled { background:var(--gray-100); color:var(--gray-500); border-color:var(--mkt-hairline); cursor:default; }
.cgc-why { font-size:13px; color:var(--error-fg); text-align:center; margin-top:9px; }

/* Template library (read-only) */
.cgt-bar { display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-bottom:14px; }
.cgt-hint { font-size:12px; color:var(--gray-500); line-height:1.6; }
.cgt-empty { background:#fff; border:1px solid var(--mkt-hairline); border-radius:12px;
  padding:28px 22px; text-align:center; font-size:14px; color:var(--gray-500); line-height:1.7; }
.cgt-empty strong { color:var(--mkt-navy); }
.cgt-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); gap:12px; }
.cgt-card { background:#fff; border:1px solid var(--mkt-hairline); border-radius:10px; padding:14px 16px; }
.cgt-card:hover { border-color:var(--mkt-gold); }
.cgt-card.arch { opacity:.62; }
.cgt-top { display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap; align-items:flex-start; }
.cgt-name { font-weight:700; font-size:15px; color:var(--mkt-navy); }
.cgt-meta { font-size:12px; color:var(--gray-500); margin-top:3px; line-height:1.5; }
.cgt-tag { font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:var(--gray-500);
  border:1px solid var(--mkt-hairline); border-radius:99px; padding:1px 7px; }
.cgt-langs { display:flex; gap:5px; flex-wrap:wrap; }
.cgt-lg { font-size:11px; padding:2px 8px; border-radius:5px; border:1px solid var(--mkt-hairline);
  background:var(--gray-50); color:var(--gray-500); font-variant-numeric:tabular-nums; }
.cgt-lg.has  { background:var(--success-bg); border-color:var(--success); color:var(--success-fg); font-weight:600; }
.cgt-lg.part { background:var(--warning-bg); border-color:var(--warning); color:var(--warning-fg); font-weight:600; }
.cgt-acts { display:flex; gap:8px; margin-top:12px; flex-wrap:wrap; }
.cgt-btn { padding:8px 14px; border-radius:8px; border:1px solid var(--mkt-hairline); background:#fff;
  color:var(--mkt-navy); font-family:inherit; font-size:13px; font-weight:600; cursor:pointer; }
.cgt-btn:hover { border-color:var(--mkt-gold); }
.cgt-btn:disabled { opacity:.55; cursor:default; }

.cgt-lab { display:block; font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--gray-500); margin:12px 0 5px; }
.cgt-in { width:100%; padding:9px 11px; border:1px solid var(--gray-200); border-radius:8px;
  font-family:inherit; font-size:13px; color:var(--mkt-navy); background:#fff; }
.cgt-in:focus { outline:2px solid var(--mkt-gold); outline-offset:1px; }
.cgt-ltabs { display:flex; gap:6px; flex-wrap:wrap; }
.cgt-lt { padding:8px 12px; border:1px solid var(--mkt-hairline); background:#fff; border-radius:8px;
  font-family:inherit; font-size:13px; font-weight:600; color:var(--gray-500); cursor:pointer; }
.cgt-lt.on { background:var(--mkt-navy); border-color:var(--mkt-navy); color:#fff; }
/* A language the template has no finished version for is disabled, not hidden — the gap is
   information, and hiding it would read as "this template is only English". */
.cgt-lt.off { opacity:.42; cursor:not-allowed; }
.cgt-prev { border:1px solid var(--mkt-hairline); border-radius:8px; overflow:hidden; background:var(--gray-50); }
.cgt-prev iframe { width:100%; height:520px; border:0; display:block; background:#f0f2f5; }
.cgt-status { font-size:13px; margin-top:10px; min-height:18px; }
.cgt-status.ok  { color:var(--success-fg); }
.cgt-status.err { color:var(--error-fg); }
/* ===== end CAMPAIGN_COMPOSE_V2 ===== */

/* ===== CAMPAIGN_IMPACT_V1 (2026-08-25) — the Campaigns landing view.
   Each panel carries its own scope note because the filter bar does not apply uniformly
   (RULE ZERO: every section states what it is measuring). */
.cgi-card { margin-top:18px; }
.cgi-card h3 { display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; }
.cgi-scope-note { font-size:11px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--gray-500); }
.cgi-na { color:var(--gray-400); }
.cgi-part { font-size:11px; color:var(--warning-fg); margin-left:6px; }
.cgi-nums { display:flex; gap:26px; flex-wrap:wrap; margin:12px 0 4px; }
.cgi-n { display:flex; flex-direction:column; }
.cgi-nv { font-size:24px; font-weight:700; color:var(--mkt-navy); font-variant-numeric:tabular-nums; line-height:1.1; }
.cgi-nk { font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:var(--gray-500); margin-top:3px; }
.cgi-bars { margin-top:14px; display:flex; flex-direction:column; gap:7px; }
.cgi-bar { display:grid; grid-template-columns:64px 1fr 74px; align-items:center; gap:10px; font-size:12px; }
.cgi-bk { color:var(--mkt-navy); font-weight:600; text-transform:uppercase; letter-spacing:.04em; }
.cgi-bt { background:var(--gray-100); border-radius:99px; height:7px; overflow:hidden; }
.cgi-bt i { display:block; height:100%; background:var(--mkt-gold); border-radius:99px; }
.cgi-bv { text-align:right; color:var(--gray-500); font-variant-numeric:tabular-nums; }
/* ===== end CAMPAIGN_IMPACT_V1 ===== */
.cgi-barhead { margin-top:16px; font-size:12px; font-weight:700; color:var(--mkt-navy); }
.cgi-barhead .cgi-na { font-weight:400; margin-left:6px; }
