/* ═══════════════════════════════════════════════════════════════════════════
   FERBE Ops — console-specific styling.

   The PRODUCT's styles.css is loaded first and does the heavy lifting: tokens,
   buttons, cards, tables, badges, form controls, the shell geometry. Everything
   here is either (a) genuinely specific to the console or (b) a small mark that
   says "this is the staff platform, not the customer one".

   ⚠️ Do NOT redefine a product component here. If a table or a pill needs to
   change, it changes in styles.css so both platforms move together — that is
   the whole reason this file is short.
   ═══════════════════════════════════════════════════════════════════════════ */

.ops-boot {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; color: var(--muted); font-size: 14px;
}

/* ── The one visual difference from the product ────────────────────────────
   The staff platform wears a dark logo tile where the customer app wears the
   brand green. One glance at the top-left answers "which platform am I in",
   which matters when the two are open in adjacent tabs and one of them can
   change prices. */
.ops-logo-icon {
  width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; color: #fff; letter-spacing: -.5px;
  background: var(--ink);
}
.ops-logo-text { font-family: var(--font-serif); font-size: 20px; color: var(--ink); letter-spacing: .5px; }
.ops-logo-tag {
  font-size: 10px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase;
  color: var(--muted); border: 1px solid var(--line); border-radius: 4px;
  padding: 2px 5px; margin-left: 2px;
}

/* ── Sign-in ───────────────────────────────────────────────────────────────
   Deliberately NOT the product's split hero. That page sells; this one lets
   four people in. A centred card on the page background is the whole design. */
.ops-login {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: var(--warm); padding: 24px;
}
.ops-login-card { width: 100%; max-width: 380px; }
.ops-login-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 28px; }
.ops-login-h { font-size: 20px; font-weight: 600; color: var(--ink); margin-bottom: 4px; letter-spacing: -.2px; }
.ops-login-sub { font-size: 14px; color: var(--slate); margin-bottom: 24px; }
.ops-login-err {
  background: var(--danger-l); color: #9A4A4A; font-size: 13px;
  padding: 9px 12px; border-radius: 8px; margin-bottom: 16px;
}
.ops-login-foot { margin-top: 20px; font-size: 12px; color: var(--muted); text-align: center; line-height: 1.6; }

/* ── Topbar ────────────────────────────────────────────────────────────────
   The product's #topbar geometry, with the staff member on the right. */
.ops-who { display: flex; align-items: center; gap: 10px; }
.ops-who-n { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.ops-who-r { font-size: 11px; color: var(--muted); }
.ops-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff; background: var(--ink);
}

/* ── Dashboard ─────────────────────────────────────────────────────────────
   Money leads, so it gets a card of its own rather than a place in the grid of
   counts: MRR and "how many customers" are different questions. */
.ops-top { display: grid; grid-template-columns: 1.4fr 1fr; gap: 14px; margin-bottom: 14px; }
@media (max-width: 1100px) { .ops-top { grid-template-columns: 1fr; } }

.ops-mrr-v {
  font-size: 40px; font-weight: 700; color: var(--ink);
  line-height: 1; letter-spacing: -2px; margin: 6px 0 8px;
}
.ops-mrr-cur { font-size: 20px; font-weight: 600; color: var(--slate); letter-spacing: 0; margin-right: 4px; }
.ops-mrr-sub { font-size: 13px; color: var(--slate); }

/* Signups per week. Bars, because eight discrete weeks are eight values, not a
   continuous line — a sparkline here would imply a trend we cannot support. */
/* ⚠️ `align-items: stretch`, NOT `flex-end`. The TRACK is the full-height grey
   column and the fill grows inside it from the bottom; with flex-end the tracks
   shrank to their 3px min-height and the whole chart rendered as a hairline. */
.ops-spark { display: flex; align-items: stretch; gap: 6px; height: 68px; margin-top: 14px; }
.ops-spark-b { flex: 1; background: var(--paper); border-radius: 4px; position: relative; }
.ops-spark-b > i {
  position: absolute; inset: auto 0 0 0; display: block;
  background: var(--accent); border-radius: 4px; min-height: 2px;
}
.ops-spark-x { display: flex; gap: 6px; margin-top: 6px; }
.ops-spark-x > span { flex: 1; text-align: center; font-size: 10px; color: var(--muted); }

/* Trials about to lapse — the one thing on this page that is time-critical. */
.ops-exp { display: flex; flex-direction: column; gap: 8px; }
.ops-exp-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
}
.ops-exp-n { font-size: 13px; font-weight: 600; color: var(--ink); }
.ops-exp-e { font-size: 11px; color: var(--muted); }
.ops-exp-d { font-size: 12px; font-weight: 700; white-space: nowrap; }
.ops-exp-d.soon { color: var(--danger); }

/* ── Plan mix ──────────────────────────────────────────────────────────────
   A bar per plan against the busiest one — the same shape as the product's
   Team workload card, and readable without a legend. */
.ops-mix { display: flex; flex-direction: column; gap: 11px; }
.ops-mix-row { display: grid; grid-template-columns: 130px 1fr 42px; align-items: center; gap: 12px; }
.ops-mix-l { font-size: 13px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ops-mix-t { height: 8px; background: var(--paper); border-radius: 4px; overflow: hidden; }
.ops-mix-f { height: 100%; background: var(--accent); border-radius: 4px; }
.ops-mix-n { font-size: 13px; font-weight: 700; color: var(--ink); text-align: right; }

/* ── Detail pages ──────────────────────────────────────────────────────────
   The product's `.pl-grid` narrow-left shape: the record on the left, what it
   does on the right. */
/* ⚠️ `minmax(0, …)`, not a bare `fr`: a bare fr track cannot shrink below its
   content's min-content width, so a wide table on the right squeezed the info
   card on the left until every one of its rows wrapped over three lines. The
   table scrolls inside `.plan-table-wrap` instead. Same trap as `.rd-mini` in
   the product. */
.ops-detail { display: grid; grid-template-columns: minmax(0, .62fr) minmax(0, 1.38fr); gap: 18px; align-items: start; }
@media (max-width: 1000px) { .ops-detail { grid-template-columns: 1fr; } }

.ops-kv { display: flex; flex-direction: column; }
.ops-kv-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.ops-kv-row:last-child { border-bottom: 0; }
.ops-kv-k { font-size: 13px; color: var(--slate); flex: none; }
.ops-kv-v { font-size: 13px; font-weight: 500; color: var(--ink); text-align: right; word-break: break-word; }
.ops-kv-v.muted { color: var(--muted); font-weight: 400; }

.ops-h { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 14px; }
.ops-sec { margin-bottom: 18px; }

/* Usage counts on an organisation — small, dense, no chrome. The question is
   "did they get started", and eight plain numbers answer it faster than cards. */
.ops-use { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
@media (max-width: 760px) { .ops-use { grid-template-columns: repeat(2, minmax(0,1fr)); } }
.ops-use-b { background: var(--paper); border-radius: 10px; padding: 12px 14px; }
.ops-use-n { font-size: 22px; font-weight: 700; color: var(--ink); line-height: 1; letter-spacing: -.8px; }
.ops-use-l { font-size: 11px; color: var(--slate); margin-top: 5px; }

/* A row that goes nowhere should not pretend to. */
.ops-row-link { cursor: pointer; }
.ops-row-link:hover { background: var(--paper); }

/* ── Product catalogue ─────────────────────────────────────────────────────
   The one page in the console that warns about its own state: deactivating the
   last public plan for an audience empties that signup path, and no column in
   the table below would say so. */
.ops-warn {
  background: var(--warning-l); color: #7A5B18;
  border-radius: 10px; padding: 12px 14px; margin-bottom: 16px;
  font-size: 13px; line-height: 1.6;
}
.ops-warn b { color: #6A4E12; }

.ops-note { font-size: 12px; color: var(--slate); line-height: 1.6; margin-bottom: 14px; }

.ops-toggle {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 11px 0; border-bottom: 1px solid var(--line); cursor: pointer;
}
.ops-toggle:last-child { border-bottom: 0; padding-bottom: 0; }
.ops-toggle input { margin-top: 2px; accent-color: var(--accent); width: 15px; height: 15px; }
.ops-toggle-l { font-size: 14px; font-weight: 500; color: var(--ink); }
.ops-toggle-h { font-size: 12px; color: var(--slate); margin-top: 2px; line-height: 1.5; }

/* ── The entitlement matrix ────────────────────────────────────────────────
   Module on the left with its capabilities beneath, grouped exactly as the
   customer sidebar groups them — so what is being sold reads in the same order
   as the thing being bought. */
.ops-mx-grp {
  font-size: 11px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
  color: var(--muted); margin: 18px 0 8px;
}
.ops-mx-grp:first-child { margin-top: 0; }
.ops-mx-row {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 13px; margin-bottom: 8px;
}
.ops-mx-row.core { background: var(--paper); border-style: dashed; }
.ops-mx-head { display: flex; align-items: center; gap: 10px; }
.ops-mx-head input { accent-color: var(--accent); width: 15px; height: 15px; }
.ops-mx-l { font-size: 14px; font-weight: 500; color: var(--ink); }
.ops-mx-core { font-size: 11px; color: var(--muted); font-weight: 400; margin-left: 8px; }

.ops-mx-caps { margin: 9px 0 0 25px; transition: opacity .15s; }
/* ⚠️ A GRID, not a wrapping flex row: twelve subject areas by four capabilities
   is a table, and its whole value is that the ticks line up in columns you can
   read down. `.ops-mx-scope` takes the first track and the caps take a fixed
   170px each — enough for "Approval workflow", the longest of them, so no row
   can wrap and put one column out of line with the rest. */
.ops-mx-line {
  display: grid; grid-template-columns: 230px repeat(4, max-content);
  align-items: center; gap: 4px 18px; padding: 3px 0;
}
/* ⚠️ A FIXED label column, not `minmax(230px, 1fr)`: the fr swallowed every
   spare pixel of the card and pushed the ticks against the right edge, a third
   of the width away from the names they belong to. Slack belongs at the end of
   the row, not in the middle of it. */
/* `max-content` per capability column takes the widest of that column across
   every row, so the columns line up while spending no more width than the
   labels need — a fixed width either wrapped "Approval workflow" or starved the
   scope column, and 230px is what holds "Audit, Compliance & Corrective
   Action", the longest group name, on one line. */
/* ⚠️ Only a SCOPED module is a table. A module with no scopes is one row of
   ticks, and giving it the grid left an empty 230px label column that pushed
   its ticks against the far right edge of the card, reading as though they
   belonged to nothing. It stays a plain row. */
.ops-mx-line:not(:has(.ops-mx-scope)) { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.ops-mx-scope { font-size: 12px; color: var(--slate); }
/* Under ~1180px of card the four columns no longer fit; fall back to wrapping,
   which is worse to read but better than a horizontal scrollbar on a form. */
@media (max-width: 1240px) {
  .ops-mx-line, .ops-mx-line:not(:has(.ops-mx-scope)) {
    display: flex; flex-wrap: wrap; gap: 6px 14px;
  }
  .ops-mx-scope { width: 230px; flex: none; }
}
/* The matrix is the widest thing on the plan page, so it sits below the two
   columns rather than inside one. */
.ops-mx-card { margin-top: 18px; }

/* ── Tax & invoice settings ────────────────────────────────────────────────
   Two per row, with the address spanning both — it is six lines tall and would
   leave a hole beside a one-line field. */
.ops-set-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 18px; margin-top: 12px;
}
.ops-set-wide { grid-column: 1 / -1; }
@media (max-width: 760px) { .ops-set-grid { grid-template-columns: 1fr; } }
/* The worked example: what the rate above does to a round number. Tinted, so
   it reads as an answer rather than another field. */
.ops-set-eg {
  margin-top: 6px; padding: 11px 13px; border-radius: 9px;
  background: var(--paper); border: 1px solid var(--line);
  font-size: 13px; color: var(--slate); line-height: 1.6;
}
.ops-set-eg b { color: var(--ink); }
/* All / None, pushed to the far end of the module's head row. */
.ops-mx-sweep { margin-left: auto; display: flex; gap: 6px; }
.ops-mx-sw {
  border: 1px solid var(--line); background: var(--white); border-radius: 6px;
  font: inherit; font-size: 11px; color: var(--slate); padding: 2px 8px; cursor: pointer;
}
.ops-mx-sw:hover { background: var(--paper); color: var(--ink); }
.ops-mx-cap { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-soft); cursor: pointer; }
.ops-mx-cap input { accent-color: var(--accent); width: 14px; height: 14px; }

/* ── The plan name's ink ───────────────────────────────────────────────────
   Four swatches, not a colour field. The three colours come from the product's
   own tokens (`--plan-*` in styles.css, which this console loads), so a
   palette change reaches both platforms at once. */
.ops-pcwrap { padding-top: 13px; border-top: 1px solid var(--line); margin-top: 12px; }
.ops-pc { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.ops-pc-o {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); background: var(--white);
  border-radius: 999px; padding: 5px 12px 5px 7px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--slate);
  transition: border-color .15s, color .15s, background .15s;
}
.ops-pc-o:hover { background: var(--paper); }
.ops-pc-o.on { border-color: var(--ink); color: var(--ink); }
.ops-pc-dot {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  background: var(--muted); box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
}
.ops-pc-o.pc-default .ops-pc-dot { background: var(--ink); }
.ops-pc-o.pc-green  .ops-pc-dot { background: var(--plan-green); }
.ops-pc-o.pc-yellow .ops-pc-dot { background: var(--plan-yellow); }
.ops-pc-o.pc-purple .ops-pc-dot { background: var(--plan-purple); }
/* The chosen one says so in its own colour — the point of the setting is what
   the customer will see, so the control should show it rather than describe it. */
.ops-pc-o.pc-green.on  { color: var(--plan-green);  border-color: var(--plan-green); }
.ops-pc-o.pc-yellow.on { color: var(--plan-yellow); border-color: var(--plan-yellow); }
.ops-pc-o.pc-purple.on { color: var(--plan-purple); border-color: var(--plan-purple); }

/* ── The written "Includes" list ───────────────────────────────────────────
   Two fields per line: the claim, and the note behind its ⓘ. The note is the
   WIDER of the two on purpose — it is a sentence, the claim is a phrase. */
.ops-inc-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ops-inc-t { flex: 1 1 40%; min-width: 0; }
.ops-inc-p { flex: 1 1 60%; min-width: 0; font-size: 12px; }
.ops-inc-x {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--white); color: var(--muted);
  font-size: 17px; line-height: 1; cursor: pointer; font-family: inherit;
  transition: background .15s, color .15s, border-color .15s;
}
.ops-inc-x:hover { background: var(--danger-l, #FDECEC); border-color: var(--danger); color: var(--danger); }
.ops-inc-fb {
  font-size: 12px; color: var(--slate); line-height: 1.6;
  background: var(--paper); border: 1px dashed var(--line);
  border-radius: 10px; padding: 10px 12px; margin-bottom: 10px;
}
.ops-inc-add { margin-top: 2px; }

/* ── Save bar ──────────────────────────────────────────────────────────────
   Sticky at the bottom: the plan page is long enough that a save button at its
   end would sit below the fold on every screen. */
.ops-savebar {
  position: sticky; bottom: 0; margin-top: 18px;
  display: flex; align-items: center; justify-content: flex-end; gap: 12px;
  background: var(--warm); border-top: 1px solid var(--line);
  padding: 14px 0;
}
.ops-savemsg { margin-right: auto; font-size: 13px; color: var(--slate); }
.ops-savemsg.err { color: var(--danger); }

/* ── Modal ─────────────────────────────────────────────────────────────────
   The console's own, deliberately minimal: the product's createModal() lives in
   app.v6.js and this platform does not load that file. */
.ops-modal-bd {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(20,24,34,.42);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.ops-modal {
  background: var(--white); border-radius: 14px; width: 100%; max-width: 440px;
  padding: 24px 28px; box-shadow: 0 18px 50px rgba(20,24,34,.22);
}
.ops-modal-h { font-size: 17px; font-weight: 600; color: var(--ink); margin-bottom: 18px; }
.ops-modal-f { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }

/* ── Billing ───────────────────────────────────────────────────────────────
   Four counts under the revenue figure. They answer "of what?", which a single
   big number never can on its own. */
.ops-billrow { display: flex; gap: 26px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.ops-billrow > div { display: flex; flex-direction: column; gap: 3px; }
.ops-billrow b { font-size: 20px; font-weight: 700; color: var(--ink); line-height: 1; letter-spacing: -.6px; }
.ops-billrow span { font-size: 12px; color: var(--slate); }

/* ── Roles ─────────────────────────────────────────────────────────────────
   A card per role, its permissions listed as chips: the question is "what can
   this role do", which reads far better as a list than as a row of ticks. */
.ops-tabs { margin-bottom: 18px; }
.ops-roles { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; align-items: start; }
.ops-role { display: flex; flex-direction: column; }
.ops-role-n { font-size: 15px; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.ops-role-c { font-size: 12px; color: var(--muted); margin-top: 3px; }
.ops-role-p { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.ops-perm {
  font-size: 12px; color: var(--ink-soft); background: var(--paper);
  border-radius: 20px; padding: 4px 10px;
}
.ops-role-all { font-size: 13px; color: var(--accent); font-weight: 500; }
.ops-role-a { display: flex; gap: 8px; margin-top: 16px; }

/* The permission tick list inside the role dialog. */
.ops-plist { max-height: 340px; overflow-y: auto; margin-top: 6px; }
.ops-ptick { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; cursor: pointer; }
.ops-ptick input { margin-top: 2px; accent-color: var(--accent); width: 15px; height: 15px; }
.ops-ptick-l { font-size: 13px; color: var(--ink); }
/* The escalation warning on staff.manage — amber, because it is the one tick
   whose consequence is not obvious from its label. */
.ops-ptick-w { font-size: 11px; color: #8C6A20; margin-top: 2px; line-height: 1.5; }

/* ── Activity ──────────────────────────────────────────────────────────────
   One line per event with the time on its own side. Same shape as the
   product's timeline: a sentence, not a table row. */
.ops-act {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.ops-act:last-child { border-bottom: 0; }
.ops-act-m { font-size: 13px; color: var(--ink); line-height: 1.5; }
.ops-act-m > span { color: var(--slate); }
.ops-act-d { font-size: 12px; color: var(--slate); margin-top: 3px; }
.ops-act-t { font-size: 12px; color: var(--muted); white-space: nowrap; flex: none; }

.ops-back { margin-bottom: 14px; }
.ops-sub { font-size: 13px; color: var(--slate); margin-top: -18px; margin-bottom: 22px; }
.ops-none { color: var(--muted); font-size: 13px; padding: 18px 0; }

/* Onboarding — the milestone editor. One row per milestone: its label, which
   shape its body takes, and the body itself. Both bodies are kept in the DOM
   and only one is shown, so switching shape does not discard what was typed. */
.oi-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 12px; }
.oi-row { border: 1px solid var(--line); border-radius: 10px; padding: 12px; background: var(--paper); }
.oi-row-top { display: grid; grid-template-columns: 1fr 150px auto; gap: 8px; margin-bottom: 8px; }
.oi-row textarea { width: 100%; }

/* ── Emails page ─────────────────────────────────────────────────────────── */
.ops-mail-split { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 14px; align-items: start; }
.ops-mail-list .sidebar-label { margin: 10px 0 4px; }
.ops-mail-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13px; color: var(--ink); }
.ops-mail-row:hover { background: var(--paper); }
.ops-mail-row.active { background: rgba(0,126,101,.11); color: var(--accent); font-weight: 600; }
.ops-mail-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 8px; }
.ops-mail-chips-l { font-size: 11px; color: var(--muted); margin-right: 2px; }
.ops-chip { font: inherit; font-size: 12px; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); background: var(--white); color: var(--ink); cursor: pointer; }
.ops-chip:hover { background: var(--paper); }
.ops-chip.req { border-color: var(--accent); color: var(--accent); }
.ops-mail-body { font-family: inherit; line-height: 1.5; resize: vertical; }
.ops-mail-err { color: var(--danger, #C0392B); font-size: 12px; min-height: 16px; margin-top: 6px; }
.ops-mail-acts { display: flex; gap: 8px; align-items: center; margin-top: 10px; }
.ops-mail-pvsubj { font-size: 13px; color: var(--slate); margin: 4px 0 8px; }
.ops-mail-preview { width: 100%; height: 520px; border: 1px solid var(--line); border-radius: 10px; background: #F5F6FA; }
.ops-mail-dom { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.ops-mail-dom:last-child { border-bottom: 0; }
.ops-mail-sent { padding: 10px 0; border-bottom: 1px solid var(--line); }
.ops-mail-sent:last-child { border-bottom: 0; }
.ops-mail-sent-s { font-size: 13px; font-weight: 600; color: var(--ink); }
.ops-mail-sent-m { font-size: 12px; color: var(--slate); margin-top: 2px; }

/* The topbar's bottom rule and the sidebar's logo rule are ONE line across
   the page: both blocks are the same fixed height, border included. */
#topbar, .sidebar-logo { height: 72px; box-sizing: border-box; }
.sidebar-logo { padding: 0 22px; }

/* Product table: one row height, one line per cell; status boxes in caps. */
.ops-plans td { height: 60px; white-space: nowrap; vertical-align: middle; }
#app-shell .badge { text-transform: uppercase; }

/* ── Plan page: the Stripe product-page shape ──────────────────────────── */
.ops-crumb { font-size: 13px; margin-bottom: 14px; }
.ops-crumb a { color: var(--accent); text-decoration: none; font-weight: 600; }
.ops-hero { display: flex; align-items: center; gap: 16px; margin-bottom: 28px; }
.ops-hero-ic { width: 56px; height: 56px; border-radius: 12px; background: var(--paper); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; color: var(--slate); }
.ops-hero-ic svg { width: 24px; height: 24px; }
.ops-hero-main { flex: 1; min-width: 0; }
.ops-hero-t { display: flex; align-items: center; gap: 10px; }
.ops-hero-t .page-title { margin: 0; }
.ops-hero-sub { font-size: 15px; color: var(--slate); margin-top: 4px; }
.ops-hero-acts { display: flex; gap: 8px; }
.ops-plan-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 40px; align-items: start; }
@media (max-width: 1100px) { .ops-plan-grid { grid-template-columns: 1fr; } }
.ops-psec { margin-bottom: 34px; }
.ops-psec-h { font-size: 20px; font-weight: 700; color: var(--ink); padding-bottom: 10px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.ops-psub { margin-top: 18px; padding-top: 14px; border-top: 1px dashed var(--line); }
.ops-psub-h { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.ops-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.ops-kv2 { display: grid; grid-template-columns: 1fr auto; gap: 10px 16px; font-size: 13px; align-items: center; }
.ops-kv2-l { color: var(--slate); }
.ops-kv2-v { color: var(--ink); font-weight: 600; text-align: right; }
.ops-psec.ops-mx-card { margin-top: 6px; }

.ops-psec-h { display: flex; align-items: center; justify-content: space-between; }
.ops-edit-btn { width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line); background: var(--white); color: var(--slate); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.ops-edit-btn:hover { color: var(--ink); background: var(--paper); }
.ops-kv2 { gap: 12px 16px; }

/* Account/organisation pages: the right-hand tables stand on their own —
   the title above, the table as its own bordered box, no card around them. */
.ops-plain { margin-bottom: 18px; }
.ops-plain .ops-none { padding: 14px 16px; border: 1px dashed var(--line); border-radius: 10px; }

.ops-user-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.ops-user-head .ops-avatar { width: 40px; height: 40px; font-size: 14px; }
.ops-kv2 .ops-kv2-v { font-weight: 500; }
