/* Business Central desktop language for the back-office portal.
 *
 * Ported from ~/Projects/fuel-trading-system/app/static/css/business-central.css
 * and mapped onto this product's shell class names (.appbar, .navrail, .tabbar,
 * .dgrid) rather than the reference's (.topbar, .rail, .tabs, .list-toolbar).
 *
 * This layer loads LAST and changes only visual grammar: no component loses its
 * behaviour, its responsive fallback or its markup. Everything is gated on
 * [data-portal="office"], which base.html sets for staff roles only — the
 * customer portal, the wallet and the POS keep the softer product look, exactly
 * as the reference keeps its consumer app out of this.
 *
 * The grammar, in one paragraph: surfaces are flat — no radius, no shadow.
 * Information density goes up. Table headers are tinted and sentence-case
 * rather than uppercase and letter-spaced, with vertical rules between columns
 * so a wide grid reads as a grid. Inputs are square and focus with an underline
 * rather than a ring. Action bars are flat transparent commands, not buttons.
 */

/* ------------------------------------------------------------- surfaces --- */

/* Flat is the single most recognisable thing about this language. A 12px
   radius and a drop shadow read as a consumer app; Business Central puts its
   information in square, bordered panes and spends no pixels on decoration. */
[data-portal="office"] .card,
[data-portal="office"] .rec-card,
[data-portal="office"] .fasttab,
[data-portal="office"] .factbox,
[data-portal="office"] .glass-card,
[data-portal="office"] .tile-card,
[data-portal="office"] .dgrid {
  border-radius: 0;
  box-shadow: none;
}
[data-portal="office"] .card {
  border: 1px solid var(--border);
  background: var(--bg-surface);
}
[data-portal="office"] .card-body { padding: var(--s-3) var(--s-4); }
[data-portal="office"] .card-body.p-0 { padding: 0; }
[data-portal="office"] body,
[data-portal="office"] .app-shell-top { background: var(--bg-app); }

/* Page heading: smaller, tighter, closer to the content it labels. */
[data-portal="office"] .page-header { margin-bottom: var(--s-3); }
[data-portal="office"] .page-header h4,
[data-portal="office"] .page-header .h4 {
  font-size: var(--fs-18);
  font-weight: var(--fw-semibold);
  letter-spacing: -.01em;
}

/* Business Central's app bar carries the app launcher and the product name,
   not a company logo. Hidden rather than removed from base_app.html, because
   that shell is shared with the CouponWallet and the customer portal, where
   the Redan mark is the customer's own branding and belongs on screen. The
   link and its accessible name are untouched — only the image goes, so the
   brand is still the way back to the home page. */
/* The product mark: a square tile in the accent, the way Business Central and
   the Microsoft apps mark an app in a dark bar. Sized to the cap height of the
   name beside it so the pair reads as one lockup rather than two elements. */
[data-portal="office"] .appbar-brand .brand-mark-logo { display: none; }
/* ...unless the shell is the customer's own storefront. The skin is ours; the
   identity is theirs. These three rules are the whole difference between a
   staff screen and a client-branded one, and they are kept together so the
   next person changing one sees the other two. */
[data-portal="office"][data-brand="client"] .appbar-brand .brand-mark-logo { display: inline-flex; }
[data-portal="office"][data-brand="client"] .brand-mark-product { display: none; }
[data-portal="office"][data-brand="client"] .rail-brand { display: none !important; }
[data-portal="office"] .appbar-brand {
  gap: var(--s-2);
  align-items: center;
}
/* The mark is the glyph, not a tile. A filled square behind it read as a
   second UI element sitting next to the product name; bare, it belongs to the
   word. The box is kept so the wordmark's baseline does not shift.
   --n-0 rather than --text-invert: the app bar is near-black in BOTH themes,
   and --text-invert flips to near-black in dark mode. */
[data-portal="office"] .brand-mark-product {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: none;
  background: none;
  color: var(--n-0);
  font-size: var(--fs-18);
}
[data-portal="office"] .appbar-brand .appbar-name {
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  letter-spacing: .01em;
}
/* Nothing under the name: the sub-label said "Back Office" and so did the
   eyebrow beside it. */
[data-portal="office"] .appbar-brand .appbar-sub { display: none; }

/* ---------------------------------------------------- module navigation ---
 * Business Central does not put its navigation down the side. The sidebar
 * becomes a horizontal module bar under the app bar, and the section's own
 * pages stay on the strip below it — which is the two-row navigation the
 * product already had the markup for.
 *
 * This is a re-layout, not a rewrite: .navrail keeps its markup, its links,
 * its badges and its mobile .tabbar counterpart. Only the axis changes, so
 * nothing about which destinations a role can reach is touched.
 *
 * Desktop only. Below 992px the rail is already hidden (d-none d-lg-flex) and
 * the .tabbar takes over, which is the right behaviour on a phone and is left
 * exactly as it was.
 */
@media (min-width: 992px) {
  /* The shell stops being a two-column flex and becomes a stack. */
  [data-portal="office"] .app-body { display: block; }
  [data-portal="office"] .app-main-col { display: block; }

  [data-portal="office"] .navrail {
    position: sticky;
    top: var(--topbar-h);
    z-index: var(--z-rail);
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    width: 100%;
    height: var(--modulebar-h);
    padding: 0 var(--s-3);
    /* MUST stay visible. CSS will not let one axis scroll while the other
       stays visible: set overflow-x to auto and overflow-y computes to auto
       beside it, whatever this file says. That clips the 2px section marker,
       and — once sections gained dropdowns — clipped every menu as well.
       Worse, opening a menu focuses its first item, the container scrolls to
       reveal it, and every section label slides out of the bar: it reads as
       the navigation vanishing rather than as a CSS mistake.
       The bar must therefore FIT at every width it applies to. */
    overflow: visible;
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border);
  }

  /* Fill the strip rather than assert a height: --modulebar-h is the bar's
     border-box and 1px of it goes to the bottom border, so an item sized to
     the token overflows by exactly that much and loses half its marker. */
  [data-portal="office"] .navrail .rail-item {
    align-self: stretch;
    min-height: 0;
    margin: 0;
    padding: 0 var(--s-3);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--fs-13);
    font-weight: var(--fw-regular);
    white-space: nowrap;
  }
  [data-portal="office"] .navrail .rail-item > i { display: none; }
  [data-portal="office"] .navrail .rail-item:hover { background: var(--bg-hover); color: var(--text); }
  [data-portal="office"] .navrail .rail-item.active,
  [data-portal="office"] .navrail .rail-item[aria-current] {
    background: transparent;
    border-bottom-color: var(--brand-600);
    color: var(--text);
    font-weight: var(--fw-medium);
  }
  /* The rail's active marker was a 3px bar pinned to the item's left edge —
     what marks the current row in a vertical sidebar, and what leaves a stray
     vertical line at the start of a horizontal one. The bottom border below
     replaces it; two markers for one state is one too many. */
  [data-portal="office"] .navrail .rail-item.active::before { content: none; }

  /* A section is a link plus a disclosure, sharing one underline so the pair
     reads as a single unit. `display: contents` outside this media query, so
     the wrapper has no effect at all on the vertical rail the customer portal
     still uses. */
  [data-portal="office"] .navrail .rail-section {
    display: flex;
    align-items: stretch;
    position: relative;
  }
  /* The chevron already separates a section from the next one, so the link
     gives up most of its right padding. That also binds the pair: the space
     WITHIN a section is now smaller than the space between two, which is the
     grouping the underline is claiming. It is what buys the bar the width the
     eight chevrons cost — without it the row needs 998px in 992px. */
  [data-portal="office"] .navrail .rail-section > .rail-item { padding-right: var(--s-1); }

  [data-portal="office"] .rail-disclose {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 24px, not the 20px the glyph wants: WCAG 2.2 §2.5.8 is a 24x24 minimum
       and eight chevrons at 20px would be eight failures. */
    width: 24px;
    min-height: 24px;
    align-self: stretch;
    padding: 0;
    border: 0;
    border-bottom: 2px solid transparent;   /* the row's underline slot */
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
  }
  [data-portal="office"] .rail-disclose:hover { color: var(--text); }
  [data-portal="office"] .rail-section.active > .rail-disclose {
    border-bottom-color: var(--brand-600);
    color: var(--text);
  }
  /* The chevron turns over while its menu is open, so the control says which
     way it will act rather than only that it can be acted on. */
  [data-portal="office"] .rail-disclose > i { transition: transform 120ms ease; }
  [data-portal="office"] .rail-disclose[aria-expanded="true"] > i { transform: rotate(180deg); }

  /* Anchored under its own section, not the bar: anchored to the bar, a menu
     belonging to a right-hand section opens off the edge of the screen. */
  [data-portal="office"] .rail-menu { margin-top: -1px; }
  [data-portal="office"] .rail-menu .dropdown-item.is-current {
    font-weight: var(--fw-semibold);
    color: var(--brand-600);
  }

  /* "More" keeps its dropdown; it just stops being pinned to the bottom of a
     column that no longer exists. */
  [data-portal="office"] .navrail .dropdown { display: flex; align-items: stretch; }
  [data-portal="office"] .navrail .dropdown.mt-auto { margin-top: 0 !important; margin-left: auto; }
  [data-portal="office"] .navrail .dropdown .rail-item { width: auto; }

  /* The product name in the module bar, as well as in the app bar above it.
     Below 1280px it is not rendered at all: the sections need 974px of a
     992px bar, so there is nothing to give it, and a name squeezed to an
     ellipsis is worse than a name that stays one row up where it already is.

     Where it does appear it yields first — flex-shrink on the brand, none on
     the nav — because a truncated product name is still the product name and a
     clipped section list is a section you cannot reach. */
  [data-portal="office"] .rail-brand { display: none; }

  /* Collapsing a horizontal bar means nothing. */
  [data-portal="office"] .rail-collapse { display: none; }

  [data-portal="office"] .tab-badge {
    margin-left: var(--s-2);
    background: var(--warn-50);
    color: var(--warn-700);
  }
}

/* The bar cannot scroll — see the overflow note above — so it has to fit, and
   measured at 992px it fits by 2px. That is not a margin, it is luck: one
   longer section label and the row spills off the card. Below the width where
   the product name joins the bar there is nothing competing for the space, so
   the sections take a tighter gutter and the row gets a real margin back. */
@media (max-width: 1279.98px) {
  [data-portal="office"] .navrail .rail-item { padding-left: var(--s-2); }
}

@media (min-width: 1280px) {
  [data-portal="office"] .rail-brand {
    display: flex;
    align-items: center;
    flex: 0 1 auto;
    min-width: 0;
    margin-right: var(--s-4);
    padding-right: var(--s-4);
    border-right: 1px solid var(--border);
    color: var(--text);
    font-size: var(--fs-16);
    font-weight: var(--fw-semibold);
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Shrink 0: the sections never give up width to the name. */
  [data-portal="office"] .navrail .rail-section,
  [data-portal="office"] .navrail > .rail-item,
  [data-portal="office"] .navrail > .dropdown { flex: 0 0 auto; }
}

/* ------------------------------------------------------- record stepping --- */

/* Working down a list of documents without going back to it. Sits with the
 * document type rather than in the command row: it is about WHERE you are, not
 * something you do to the record. */
[data-portal="office"] .record-step {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  margin-left: var(--s-3);
  vertical-align: middle;
}
[data-portal="office"] .record-step-go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* WCAG 2.2 §2.5.8 again: 24px minimum, whatever the glyph wants. */
  width: 24px;
  height: 24px;
  border: 1px solid var(--border);
  background: var(--bg-surface);
  color: var(--text-muted);
  text-decoration: none;
}
[data-portal="office"] a.record-step-go:hover {
  background: var(--bg-hover);
  color: var(--text);
}
/* The end of the list. Kept in place rather than removed so the count does not
   jump sideways on the first and last record. */
[data-portal="office"] .record-step-go.is-spent {
  opacity: .4;
  cursor: default;
}
[data-portal="office"] .record-step-count {
  color: var(--text-subtle);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
  letter-spacing: 0;
  text-transform: none;
}

/* --------------------------------------------------------------- fields --- */

/* An editable field reads as a ledger line: what it is on the left, what it
 * holds on the right, a dotted leader carrying the eye across the gap. The
 * read-only facts on a document already read this way; this is the same
 * grammar for the fields you can type into, which is what makes a Business
 * Central card page recognisable at a glance.
 *
 * Opt-in via .form-ledger on the row, not automatic: .form-label is also worn
 * by filter bars, search boxes and modals that are not field ledgers, and
 * quietly re-laying those out is how a stylesheet stops being predictable.
 *
 * Desktop only. Two columns need width; below this the stacked layout the
 * form already has is the right one.
 */
@media (min-width: 992px) {
  [data-portal="office"] .form-ledger > [class*="col-"] {
    display: grid;
    grid-template-columns: minmax(8rem, 34%) 1fr;
    align-items: baseline;
    column-gap: var(--s-3);
  }
  /* A field with no label of its own — a checkbox, a switch, a lone button —
     is not a ledger line and takes the whole width rather than sitting in an
     empty second column. */
  [data-portal="office"] .form-ledger > [class*="col-"]:not(:has(> .form-label)) {
    grid-template-columns: 1fr;
  }
  [data-portal="office"] .form-ledger > [class*="col-"] > .form-label {
    grid-column: 1;
    display: flex;
    align-items: baseline;
    gap: var(--s-2);
    margin: 0;
    color: var(--text-muted);
    font-weight: var(--fw-regular);
  }
  /* The leader is drawn on the label's own baseline, not under its descenders,
     which is why it is nudged up rather than left where a border falls. */
  [data-portal="office"] .form-ledger > [class*="col-"] > .form-label::after {
    content: "";
    flex: 1 1 auto;
    min-width: var(--s-4);
    border-bottom: 1px dotted var(--border-strong, var(--border));
    transform: translateY(-0.3em);
  }
  /* Only a row that HAS a label puts its control in the second column. Written
     as :has rather than as an override on the label-less case because the two
     would carry identical specificity, and the one that happened to come last
     in the file would win — which is how section headings ended up pinned to
     the right edge in an implicit column. */
  [data-portal="office"] .form-ledger > [class*="col-"]:has(> .form-label) > *:not(.form-label) {
    grid-column: 2;
  }
}

/* ---------------------------------------------------------------- lists --- */

/* The header row follows the reference: a faint neutral tint, muted
   sentence-case text, and NOT letter-spaced uppercase — tracking costs width
   in a grid that needs every pixel for data. The tokens are the same ones the
   base table uses, so the staff skin adds density and selection, not a second
   header style. */
[data-portal="office"] .table thead th {
  padding: var(--table-head-py) var(--s-3);
  background: var(--table-head-bg);
  border-top: 1px solid var(--table-rule);
  border-bottom: 1px solid var(--table-head-rule);
  color: var(--table-head-text);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  text-transform: none;
  letter-spacing: 0.2px;
}

/* Ruled horizontally only. The vertical rules that used to sit here were a
   Business Central mannerism the reference dropped, and with the taller rows
   and the header tint a row already reads as a line; the last row's rule is
   dropped because the card draws that edge. */
[data-portal="office"] .table tbody td { border-bottom: 1px solid var(--table-rule); }
[data-portal="office"] .table tbody tr:last-child td { border-bottom: 0; }

[data-portal="office"] .table > :not(caption) > * > * { padding: var(--row-py) var(--s-3); }
[data-portal="office"] .table > :not(caption) > * > :first-child { padding-left: var(--table-gutter); }
[data-portal="office"] .table > :not(caption) > * > :last-child { padding-right: var(--table-gutter); }
[data-portal="office"] .table tbody tr:hover { background: var(--table-hover); }
[data-portal="office"] .table tbody tr[aria-selected="true"] td { background: var(--brand-100); }

/* The grid toolbar ux.js builds: flush with the table, underlined controls. */
[data-portal="office"] .dgrid-toolbar {
  min-height: 42px;
  padding: var(--s-1) var(--s-2);
  border-bottom: 1px solid var(--border);
  border-radius: 0;
}
[data-portal="office"] .dgrid-filter input,
[data-portal="office"] .dgrid-toolbar select {
  height: 32px;
  border: 0;
  border-bottom: 1px solid var(--border-strong);
  border-radius: 0;
  background: var(--bg-surface);
}

/* --------------------------------------------------------------- fields --- */

/* Square, and focus underlines rather than rings — the Fluent field. */
[data-portal="office"] .form-control,
[data-portal="office"] .form-select,
[data-portal="office"] .input-group-text {
  border-color: var(--border-strong);
  border-radius: 0;
  background-color: var(--bg-surface);
}
[data-portal="office"] .form-control:focus,
[data-portal="office"] .form-select:focus {
  border-color: var(--brand-600);
  box-shadow: inset 0 -2px 0 var(--brand-600);
}
[data-portal="office"] .form-label,
[data-portal="office"] .form-label.small {
  color: var(--text-muted);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
}

/* -------------------------------------------------------------- actions --- */

/* Commands, not buttons: flat and transparent until hovered. The primary
   action keeps its fill so there is still exactly one obvious next step. */
[data-portal="office"] .document-actions {
  min-height: 42px;
  margin-bottom: var(--s-3);
  padding: 0;
  border-bottom: 1px solid var(--border);
}
[data-portal="office"] .document-action-group { min-height: 42px; padding: 0 var(--s-3); }
[data-portal="office"] .document-action-group:first-child { padding-left: 0; }
[data-portal="office"] .document-actions .btn {
  min-height: 34px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-weight: var(--fw-regular);
}
[data-portal="office"] .document-actions .btn:hover { background: var(--brand-50); color: var(--brand-700); }
[data-portal="office"] .document-actions .btn-brand,
[data-portal="office"] .document-actions .btn-primary {
  background: var(--brand-600);
  color: var(--text-invert);
  font-weight: var(--fw-medium);
}
[data-portal="office"] .document-actions .btn-brand:hover { background: var(--brand-700); color: var(--text-invert); }
[data-portal="office"] .document-actions .btn-outline-danger { color: var(--neg-700); }

/* Buttons generally: square corners, so they belong to the same language. */
[data-portal="office"] .btn { border-radius: 0; }
/* Buttons square off, badges do not: the reference keeps its status pills
   rounded, and squaring them here was my own invention rather than
   something the reference does. */

/* ------------------------------------------------------- list FactBox --- */

/* The pane beside a list showing the selected row in full, built by ux.js from
   the table's own headers and cells. Below 1200px it is not rendered at all:
   the grid itself is already the narrower thing on screen, and on a phone the
   .as-cards fallback has replaced the table entirely. */
[data-portal="office"] .list-layout { min-width: 0; }
[data-portal="office"] .list-factbox { display: none; }

@media (min-width: 1200px) {
  [data-portal="office"] .list-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 320px);
    gap: var(--s-5);
    align-items: start;
  }
  [data-portal="office"] .list-factbox {
    display: block;
    position: sticky;
    top: calc(var(--topbar-h) + var(--modulebar-h) + var(--s-4));
    max-height: calc(100vh - var(--topbar-h) - var(--modulebar-h) - var(--s-8));
    padding-left: var(--s-4);
    border-left: 1px solid var(--border);
    overflow-y: auto;
  }
}

[data-portal="office"] .list-factbox-title { display: grid; gap: 2px; margin-bottom: var(--s-4); }
[data-portal="office"] .list-factbox-title strong {
  overflow-wrap: anywhere;
  font-size: var(--fs-18);
  font-weight: var(--fw-medium);
}
[data-portal="office"] .list-factbox-title span { color: var(--brand-700); font-size: var(--fs-12); }
[data-portal="office"] .list-factbox-fields { display: grid; margin: 0; }
[data-portal="office"] .list-factbox-fields > div {
  display: grid;
  grid-template-columns: minmax(96px, .8fr) minmax(0, 1.2fr);
  gap: var(--s-3);
  padding: var(--s-2) 0;
  border-bottom: 1px dotted var(--border);
}
[data-portal="office"] .list-factbox-fields dt { color: var(--text-muted); font-size: var(--fs-12); }
[data-portal="office"] .list-factbox-fields dd {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--text);
  font-size: var(--fs-12);
  font-weight: var(--fw-medium);
  text-align: right;
}

/* The selected row. A list without a pane never sets aria-selected, so this
   costs nothing where the browser is not in use. */
[data-portal="office"] .table tbody tr[aria-selected="true"] td { background: var(--brand-50); }
[data-portal="office"] .table tbody tr[aria-selected="true"] td:first-child {
  box-shadow: inset 3px 0 0 var(--brand-600);
}
[data-portal="office"] .table tbody tr:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: -2px;
}

/* --------------------------------------------------------------- reports --- */

/* The Insights page: headline figures, then ONE catalogue card listing every
   report in named columns. Ported from the reference, which treats the page as
   a table of contents rather than as a set of unrelated report cards. */

[data-portal="office"] .card-header h2 {
  margin: 0;
  font-size: var(--fs-13);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .card-header-hint {
  color: var(--text-subtle);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
}

/* Third-level navigation: the pages that belong to one thing. Pills, sized
   below the section strip so the hierarchy reads at a glance — module bar,
   section strip, then this. */
[data-portal="office"] .subnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
}
[data-portal="office"] .subnav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-pill);
  color: var(--text-muted);
  font-size: var(--fs-13);
  text-decoration: none;
}
[data-portal="office"] .subnav-link:hover { background: var(--brand-50); color: var(--brand-700); }
[data-portal="office"] .subnav-link .bi { color: inherit; }
[data-portal="office"] .subnav-link.is-on {
  background: var(--brand-600);
  color: var(--text-invert);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .subnav-link:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}

/* A filter bar that lays itself out. These were built from 12-column
   arithmetic — the coupon register asked for 3+2+1+2+2+2+2 = 14 columns, so it
   wrapped, and each date RANGE was squeezed into 2/12 so its from/to inputs
   stacked on top of each other. A grid sizes to content instead of to a sum,
   and a range simply asks for two columns. */
[data-portal="office"] .filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--s-3);
  align-items: end;
}
[data-portal="office"] .filter-grid > * { min-width: 0; }
[data-portal="office"] .filter-grid .is-range { grid-column: span 2; }
[data-portal="office"] .filter-grid .is-range .range-pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-2);
}
[data-portal="office"] .filter-grid .is-range .range-sep {
  color: var(--text-subtle);
  font-size: var(--fs-12);
}
/* The actions end the bar rather than sitting in a column of their own. */
[data-portal="office"] .filter-grid .filter-actions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
@media (max-width: 700px) {
  [data-portal="office"] .filter-grid .is-range { grid-column: span 1; }
}

/* Quick date ranges under a report's filter. Pills, because they are a set of
   alternatives rather than commands — and the one in force is filled, so the
   period on screen is legible without reading two date inputs. */
[data-portal="office"] .range-presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-3);
}
[data-portal="office"] .range-preset {
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  background: var(--bg-surface);
  color: var(--text);
  font-size: var(--fs-12);
  text-decoration: none;
  white-space: nowrap;
}
[data-portal="office"] .range-preset:hover {
  border-color: var(--brand-600);
  color: var(--brand-700);
}
[data-portal="office"] .range-preset.is-on {
  background: var(--brand-600);
  border-color: var(--brand-600);
  color: var(--text-invert);
}
[data-portal="office"] .range-preset:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}

/* Reporting IN litres should make the litres number the figure. The two
   measures were never peers in this markup — value was the headline and litres
   the caption under it — so choosing Litres left every tile showing a small
   grey "0 L" under a label and no figure at all. Presentation only: the same
   element, promoted for the mode that asked for it. */
[data-portal="office"] .units-litres .kpi-meta.u-litres {
  margin-top: var(--s-1);
  color: var(--brand-700);
  font-size: var(--fs-28);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

/* The measure switch: Value / Litres / Both. It existed as three small grey
   buttons in the filter row and read as nothing in particular; as a segmented
   control it says there is a choice and which half is in force. */
[data-portal="office"] .measure-switch {
  display: inline-flex;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  overflow: hidden;
}
[data-portal="office"] .measure-switch a {
  padding: var(--s-1) var(--s-3);
  background: var(--bg-surface);
  color: var(--text);
  font-size: var(--fs-12);
  text-decoration: none;
  white-space: nowrap;
}
[data-portal="office"] .measure-switch a + a { border-left: 1px solid var(--border-strong); }
[data-portal="office"] .measure-switch a:hover { background: var(--brand-50); color: var(--brand-700); }
[data-portal="office"] .measure-switch a.is-on {
  background: var(--brand-600);
  color: var(--text-invert);
  font-weight: var(--fw-semibold);
}

/* A report's own note: what it covers and the "Data as at" stamp. It sits
   outside .page-header on purpose — that band is hidden where the section strip
   already names the page, and this is not a duplicate of anything. */
[data-portal="office"] .report-note {
  max-width: 90ch;
  margin: var(--s-3) 0 var(--s-4);
  color: var(--text-muted);
  font-size: var(--fs-13);
  line-height: 1.5;
}
[data-portal="office"] .report-note .xsmall { color: var(--text-subtle); }

/* The filter bar every report opens with: flush, underlined controls, no card
   frame of its own — the same treatment the list toolbar gets. */
[data-portal="office"] form.card {
  margin-bottom: var(--s-4);
  border-color: var(--border);
}
[data-portal="office"] form.card .form-label {
  color: var(--text-muted);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
}

[data-portal="office"] .kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}
[data-portal="office"] .kpi {
  display: block;
  padding: var(--s-4);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  color: inherit;
  text-decoration: none;
}
/* Outlined, not filled. The dashboard's tiles are filled because they ARE the
   page; here they sit above a catalogue that wants the attention. */
[data-portal="office"] a.kpi:hover { border-color: var(--brand-300); }
[data-portal="office"] a.kpi:focus-visible { outline: 2px solid var(--brand-600); outline-offset: -2px; }
/* styles.css sets .kpi-label uppercase, 10.5px and letter-spaced — the
   consumer-dashboard voice. The reference names a figure the way a sentence
   would: "Revenue", "Gross margin". Restated in full because the legacy rule
   is a single class and would otherwise win on nothing but load order. */
[data-portal="office"] .kpi-label {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--text-muted);
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  letter-spacing: 0;
  text-transform: none;
}
[data-portal="office"] .kpi-label .bi { color: var(--text-subtle); }
[data-portal="office"] .kpi-value {
  display: block;
  margin-top: var(--s-1);
  color: var(--brand-700);
  font-size: var(--fs-28);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
[data-portal="office"] .kpi-meta {
  display: block;
  margin-top: var(--s-1);
  color: var(--text-subtle);
  font-size: var(--fs-12);
}

[data-portal="office"] .report-catalogue {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s-5) var(--s-6);
}
[data-portal="office"] .link-group { min-width: 0; }
[data-portal="office"] .section-heading {
  margin: 0 0 var(--s-2);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .link-group .related-link { border-radius: 0; }
[data-portal="office"] .link-group .related-link + .related-link {
  border-top: 1px solid var(--border);
}
[data-portal="office"] .link-group .related-link-copy strong { color: var(--brand-700); }

/* ------------------------------------------------------------ dashboard --- */

/* These rules were a 20-line <style> block inside admin/dashboard.html — the
   last place in the back office where a component was styled in a template.
   Same classes, tokens instead of hardcoded pixels and legacy variables. */

[data-portal="office"] .dash-headline { padding: var(--s-5) 0 var(--s-4); }
[data-portal="office"] .dash-eyebrow {
  margin: 0 0 var(--s-2);
  color: var(--text-subtle);
  font-size: var(--fs-11);
  font-weight: var(--fw-semibold);
  letter-spacing: .07em;
  text-transform: uppercase;
}
[data-portal="office"] .dash-headline h1 {
  margin: 0;
  max-width: 46ch;
  color: var(--text);
  font-size: var(--fs-28);
  font-weight: var(--fw-regular);
  line-height: 1.25;
}
/* The number the sentence is about, in the accent. The reference leads with
   the count of things wanting a person rather than with a greeting. */
[data-portal="office"] .dash-headline-count {
  color: var(--brand-600);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 1200px) {
  [data-portal="office"] .dash-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
    gap: var(--s-6);
    align-items: start;
  }
}
[data-portal="office"] .dash-main { min-width: 0; }

[data-portal="office"] .dash-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin: var(--s-4) 0 var(--s-3);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--border);
}
[data-portal="office"] .dash-head h2 {
  margin: 0;
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .dash-hint { color: var(--text-subtle); font-size: var(--fs-12); }

[data-portal="office"] .dash-group { margin-bottom: var(--s-4); }
[data-portal="office"] .dash-group-label {
  margin-bottom: var(--s-2);
  color: var(--text-subtle);
  font-size: var(--fs-11);
  font-weight: var(--fw-semibold);
  letter-spacing: .07em;
  text-transform: uppercase;
}
[data-portal="office"] .dash-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1px;
  background: var(--border);
}
/* Filled, in the accent, and butted together with a 1px gap showing the
   background through — the reference's tiles read as one block of position
   rather than as four separate cards competing with the tables below. */
[data-portal="office"] .dash-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-height: 116px;
  padding: var(--s-4);
  background: var(--brand-600);
  color: var(--text-invert);
  text-decoration: none;
}
[data-portal="office"] .dash-tile:hover { background: var(--brand-700); }
[data-portal="office"] .dash-tile:focus-visible { outline: 2px solid var(--brand-800); outline-offset: -2px; }
[data-portal="office"] .dash-tile-label { font-size: var(--fs-13); font-weight: var(--fw-semibold); }
[data-portal="office"] .dash-tile-value {
  font-size: var(--fs-28);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
[data-portal="office"] .dash-tile-sub { font-size: var(--fs-12); opacity: .82; }
[data-portal="office"] .dash-tile-go {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  opacity: .7;
}

[data-portal="office"] .dash-attention { min-width: 0; }
[data-portal="office"] .dash-attention-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 var(--s-2);
  border-radius: var(--r-pill);
  background: var(--neg-50);
  color: var(--neg-700);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
}

/* The queue panels: same rows, flat surfaces. */
[data-portal="office"] .qgroup {
  margin-bottom: var(--s-4);
  background: var(--bg-surface);
  border: 1px solid var(--border);
}
[data-portal="office"] .qgroup .qh {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 38px;
  padding: var(--s-2) var(--s-3);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-13);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .qgroup .qh > .bi { color: var(--brand-600); }
[data-portal="office"] .qgroup .qh .focus {
  margin-left: auto;
  padding: 1px var(--s-2);
  border-radius: var(--r-pill);
  background: var(--warn-50);
  color: var(--warn-700);
  font-size: var(--fs-11);
  font-weight: var(--fw-semibold);
  letter-spacing: .04em;
  text-transform: uppercase;
}
[data-portal="office"] .qrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
}
[data-portal="office"] .qrow:last-child { border-bottom: 0; }
[data-portal="office"] .qrow:hover { background: var(--brand-50); }
[data-portal="office"] .qrow > .bi { width: 20px; color: var(--brand-600); text-align: center; }
[data-portal="office"] .qrow .t { flex: 1; min-width: 0; font-size: var(--fs-13); }
[data-portal="office"] .qrow .c {
  min-width: 34px;
  font-family: var(--font-mono);
  font-size: var(--fs-13);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-semibold);
  text-align: right;
}
[data-portal="office"] .qrow .badge-att {
  padding: 1px var(--s-2);
  border-radius: var(--r-pill);
  background: var(--neg-50);
  color: var(--neg-700);
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .qrow .badge-ok { color: var(--text-subtle); font-size: var(--fs-12); }

/* ----------------------------------------------------- workspace bar --- */

/* Below the module-bar breakpoint the strip and the mobile tab row stack as
   they always have; the wrapper is a plain block and changes nothing. */
/* Below the module-bar breakpoint the slot is a plain block under the tabs;
   without a gutter its button runs to both edges of the viewport. */
@media (max-width: 991.98px) {
  [data-portal="office"] .workspace-actions:not(:empty) {
    display: flex;
    gap: var(--s-2);
    padding: var(--s-2) var(--s-4);
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border);
  }
}

@media (min-width: 992px) {
  /* The commands used to share the strip's row, pinned right. That reads well
     with one command and a short strip — which is the reference's case — and
     fails here: Finance has seven tabs needing 1184px, the commands took 317px
     of the 1200 available, and the strip clipped. On Bank statements the tab
     scrolled out of sight was the ACTIVE one, so the page stopped saying where
     you were. Two things cannot share one row when either can grow.

     They get a row each. It costs 38px of height and buys a strip that always
     shows the current tab and commands that always sit in the same place. */
  [data-portal="office"] .workspace-bar {
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border);
  }
  [data-portal="office"] .workspace-bar > .subtabbar { border-bottom: 0; }
  [data-portal="office"] .workspace-actions {
    display: flex;
    gap: var(--s-1);
    align-items: center;
    justify-content: flex-end;
    min-height: 38px;
    padding: 0 var(--s-4);
    border-top: 1px solid var(--border);
  }
  /* A page that supplies no commands must not leave a rule hanging in the
     strip. `:empty` is exact here — the slot holds either markup or nothing,
     never whitespace, because the block renders on one line. */
  [data-portal="office"] .workspace-actions:empty { display: none; }
  [data-portal="office"] .workspace-actions .btn {
    height: 34px;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--text);
    font-weight: var(--fw-regular);
  }
  [data-portal="office"] .workspace-actions .btn:hover {
    background: var(--brand-50);
    color: var(--brand-700);
  }
  [data-portal="office"] .workspace-actions .btn-brand,
  [data-portal="office"] .workspace-actions .btn-primary {
    color: var(--brand-700);
    font-weight: var(--fw-semibold);
  }

  /* The page's name was on screen three times: the strip's active tab, the
     breadcrumb's last crumb, and this heading. The reference shows it once.
     Two conditions keep this safe rather than blanket:
       :has(.subtab.is-exact)    the strip names THIS page, not merely the
                                 section it lives under. `.active` was the
                                 obvious selector and the wrong one: it is a
                                 prefix match, so /admin/quotations/new lit the
                                 Quotations tab and lost its own heading,
                                 "New quotation — choose customer", which no
                                 other element on the page carried;
       :not(:has(.page-actions)) the band holds no commands, so nothing is lost
                                 with it. A template still keeping its buttons
                                 there is left alone until it moves them up. */
  [data-portal="office"] .workspace-bar:has(.subtab.is-exact) ~ .app-content .page-header:not(:has(.page-actions)) {
    display: none;
  }
}

/* --------------------------------------------------------- record pages --- */

/* The header is a band, not a card. The reference gives it no frame at all and
   divides it from the body with a single strong rule. */
[data-portal="office"] .document-head {
  margin-bottom: 0;
  padding: var(--s-3) 0;
  background: var(--bg-surface);
  border: 0;
  border-bottom: 1px solid var(--border-strong);
}

/* Large and light. A bold 22px number competes with the page for attention;
   Business Central sets the document number at display size in the regular
   weight and lets the status badge beside it carry the emphasis. */
[data-portal="office"] .document-title-row h1 {
  font-size: var(--fs-28);
  font-weight: var(--fw-regular);
  letter-spacing: 0;
}

/* The header is a flex row of heading + facts, and the facts block had no
   basis of its own — so it shrank to its content, its auto-fit grid collapsed
   to a single column, and five facts stacked into a tall narrow strip that
   left the rest of the band empty. Give it the remaining width and it lays
   out across the header the way the reference does. */
[data-portal="office"] .document-facts {
  flex: 1 1 420px;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--s-3) var(--s-5);
}

/* Sentence case throughout. Uppercase letter-spaced labels are this product's
   consumer voice; the desktop one names its fields the way a form does. */
[data-portal="office"] .document-fact-label {
  font-size: var(--fs-12);
  letter-spacing: 0;
  text-transform: none;
}

/* §7: a calculated value must not look editable. Here it says so in a word
   rather than with a tint, which keeps the header a single flat surface. */
[data-portal="office"] .document-fact.is-calculated .document-fact-value {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-weight: var(--fw-semibold);
}
[data-portal="office"] .document-fact.is-calculated .document-fact-value::after {
  content: "Calculated";
  display: inline-block;
  margin-left: var(--s-2);
  color: var(--text-subtle);
  font-size: var(--fs-11);
  font-weight: var(--fw-medium);
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* FastTabs read as rules laid across the page, not as a stack of panels: the
   section border is the top edge of its own summary. */
[data-portal="office"] .fasttab {
  margin-bottom: 0;
  border-top: 0;
  border-right: 0;
  border-left: 0;
  border-color: var(--border);
}
[data-portal="office"] .fasttab > summary {
  min-height: 38px;
  padding: var(--s-2) var(--s-3);
  background: transparent;
  border-top: 1px solid var(--border-strong);
}
[data-portal="office"] .fasttab-body { padding: var(--s-3); }
/* components.css says `.fasttab-body.flush { padding: 0 }` — two classes, which
   ties with the attribute-plus-class rule above and is settled by load order.
   This file loads last, so restate it or a table inside a FastTab carries
   padding the same table in a card does not. */
[data-portal="office"] .fasttab-body.flush { padding: 0; }

/* A card inside a FastTab is a frame inside a frame. The reference has no such
   nesting — a section within a tab is separated by space, not by a border —
   and the pages converted so far kept the card each section arrived in. */
[data-portal="office"] .fasttab-body > .card {
  background: transparent;
  border: 0;
  box-shadow: none;
}
[data-portal="office"] .fasttab-body > .card > .card-body { padding: 0; }

/* The FactBox pane is a column beside the document, divided from it by a rule,
   with every heading underlined in the accent. After the module bar that
   underline is the most recognisable mark on a Business Central page. */
[data-portal="office"] .factbox-pane {
  gap: var(--s-5);
  padding-left: var(--s-4);
  border-left: 1px solid var(--border);
}
[data-portal="office"] .factbox { background: transparent; border: 0; }
[data-portal="office"] .factbox-head {
  min-height: 38px;
  padding: var(--s-2) 0;
  background: transparent;
  border-bottom: 2px solid var(--brand-600);
}
[data-portal="office"] .factbox-head h2 {
  color: var(--text);
  font-size: var(--fs-13);
  letter-spacing: 0;
  text-transform: none;
}
[data-portal="office"] .factbox-head h2 .bi { color: var(--brand-600); }
[data-portal="office"] .factbox-body { padding: var(--s-3) 0; }

/* Read-only facts read as a ledger: label left, value right, a dotted leader
   carrying the eye across the gap between them. The `dl` in these pages is
   flat — dt and dd are siblings with no wrapper — so the grid is declared on
   the list itself and each cell draws its own half of the rule.
   `.row` is excluded: that is Bootstrap's two-column dl, which brings its own
   grid and would fight this one. */
/* `.list-factbox-fields` is excluded: it is a dl whose CHILDREN are the rows
   (each a <div> holding its own dt/dd), so imposing a two-column grid on the
   list itself flows two fields onto every line and wraps both to pieces. */
[data-portal="office"] .fasttab-body dl:not(.row):not(.list-factbox-fields),
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) {
  display: grid;
  grid-template-columns: minmax(110px, 0.9fr) minmax(0, 1.1fr);
  align-items: baseline;
  margin: 0;
}
[data-portal="office"] .fasttab-body dl:not(.row):not(.list-factbox-fields) > dt,
[data-portal="office"] .fasttab-body dl:not(.row):not(.list-factbox-fields) > dd,
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) > dt,
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) > dd {
  padding: var(--s-2) 0;
  border-bottom: 1px dotted var(--border);
}
[data-portal="office"] .fasttab-body dl:not(.row):not(.list-factbox-fields) > dt,
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) > dt {
  color: var(--text-muted);
  font-size: var(--fs-12);
  font-weight: var(--fw-regular);
}
[data-portal="office"] .fasttab-body dl:not(.row):not(.list-factbox-fields) > dd,
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) > dd {
  margin: 0;
  overflow-wrap: anywhere;
}
/* In the pane the column is narrow and the value hugs the right edge, as the
   reference's list FactBox does; in the document body it stays left-aligned
   against its label, where the eye is already travelling. */
[data-portal="office"] .factbox-body dl:not(.row):not(.list-factbox-fields) > dd {
  font-weight: var(--fw-medium);
  text-align: right;
}

/* ------------------------------------------------------------- dialogs --- */

[data-portal="office"] .modal-content { border-radius: 0; box-shadow: var(--shadow-lg); }
[data-portal="office"] .dropdown-menu { border-radius: 0; }
[data-portal="office"] .dropdown-item { border-radius: 0; }

/* ------------------------------------------- reference finishing (2026-09) --- */
/* The MyWetStock reference's working surface, on top of the Business Central
   grammar: rounded bordered panels, underline section tabs, 3px-radius
   controls and chips, 14px cells. The app bar and module bar are untouched;
   this is the page, not the chrome. */

/* Panels: a 1px border and a soft radius, not a flat square. */
[data-portal="office"] .card,
[data-portal="office"] .dgrid { border-radius: var(--r-md); }
[data-portal="office"] .card > .table-responsive:last-child,
[data-portal="office"] .card > .card-body.p-0:last-child { border-radius: 0 0 var(--r-md) var(--r-md); overflow: hidden; }

/* The page heading reads as the panel's own title line: a medium-weight
   title with a one-line muted hint under it. */
[data-portal="office"] .page-header h4,
[data-portal="office"] .page-header .h4 {
  font-size: var(--fs-18);
  font-weight: var(--fw-medium);
  letter-spacing: 0;
}
[data-portal="office"] .page-header .text-muted { font-size: var(--fs-13); }

/* Section tabs: quiet text with an underline, not a filled pill. Icons go;
   the words carry it. The section label keeps its place but drops its
   uppercase tracking. */
[data-portal="office"] .subtabbar { background: var(--bg-surface); padding: 0; }
[data-portal="office"] .subtab-scroll { gap: var(--s-5); padding: 0 var(--s-5); }
[data-portal="office"] .subtab-section {
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  letter-spacing: .3px;
  text-transform: none;
  color: var(--text-subtle);
  padding: 0 var(--s-4) 0 0;
  margin: 0;
}
[data-portal="office"] .subtab-section .bi { color: var(--brand-600); }
[data-portal="office"] .subtab {
  padding: 12px 2px;
  border-radius: 0;
  border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  box-shadow: none;
}
[data-portal="office"] .subtab .bi { display: none; }
[data-portal="office"] .subtab:hover { background: transparent; color: var(--brand-700); }
[data-portal="office"] .subtab.active {
  background: transparent;
  color: var(--brand-700);
  border-bottom-color: var(--brand-600);
  font-weight: var(--fw-semibold);
  box-shadow: none;
}
[data-portal="office"] .subtab-badge { border-radius: var(--r-sm); }

/* Controls and chips: 3px corners, the reference's one radius for anything
   you press or read as a state. Chips are sentence case in the markup, so no
   transform is needed here — and none is applied. */
[data-portal="office"] .btn { border-radius: 3px; }
[data-portal="office"] .btn-outline-secondary {
  border-color: var(--n-300);
  color: var(--text-muted);
  background: var(--bg-surface);
}
[data-portal="office"] .btn-outline-secondary:hover {
  border-color: var(--brand-300);
  background: var(--brand-50);
  color: var(--brand-800);
}
[data-portal="office"] .badge {
  border-radius: 3px;
  padding: 4px var(--s-2);
  font-size: var(--fs-12);
  font-weight: var(--fw-medium);
  letter-spacing: 0;
}

/* Cells at the reference's 14px; the header stays at 12. */
[data-portal="office"] .table { font-size: var(--fs-14); }

