/* ============================================================================
   kaixa - VARIANT A - "CONFIDENT UTILITY"
   ----------------------------------------------------------------------------
   The app as an INSTRUMENT: a petrol pump, a weighing scale, a Braun calculator.
   Not a card-based dashboard.

   Four rules the whole system obeys:
     1. INK ON BONE. Near-black on warm off-white. One signal green, spent only
        on money coming in. Nothing is grey-on-grey - this screen gets read in
        direct sun on a cracked 5" display.
     2. NO SHADOWS, NO SOFT CORNERS. Elevation is expressed by INVERSION (an ink
        panel) and by HAIRLINES, never by blur. Radii are 0-3px.
     3. THE NUMBER IS THE PRODUCT. Money sets in Archivo 800, tabular figures,
        and NARROWS along its own width axis rather than wrapping or being
        truncated. A number here is never allowed to go missing (CONV-144).
     4. DENSITY IS RESPECT. A merchant selling at 6pm wants nine products in
        thumb reach, not four. Rows, not tiles.

   Motion is mechanical: 90-120ms, no bounce. A press INVERTS; it does not
   float. Anything springy belongs to variant B.
   ========================================================================= */

/* -------------------------------------------------------------- typeface */
/* Archivo variable (Omnibus-Type, OFL). Subset to Latin + PT diacritics, width
   axis clamped to 78-100 - the condensed end is a working tool here, not
   decoration: it is what keeps a six-figure total on one line. */
@font-face {
  font-family: "Archivo";
  src: url("./fonts/archivo.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 78% 100%;
  font-style: normal;
  font-display: block; /* preloaded in index.html, so this never blocks visibly */
}

:root {
  color-scheme: light;

  /* Ink and paper. --paper is bone, never #fff: pure white plus grey borders is
     the exact signature of an unfinished admin form. */
  --paper: #faf9f5;
  --paper-raised: #ffffff;
  --ink: #0a0a0a;
  --ink-2: #333230;
  --ink-3: #6a6862; /* 5.29:1 on --paper, measured - the lightest text allowed */
  --ink-inverse: #faf9f5;

  /* Hairlines are ink at low alpha, so they darken with the type instead of
     floating as a separate grey system. */
  --rule: rgba(10, 10, 10, 0.14);
  --rule-strong: rgba(10, 10, 10, 0.32);
  --rule-inverse: rgba(250, 249, 245, 0.22);

  /* One signal colour. --signal is for text and hairlines on paper (7.4:1);
     --signal-bright is a FILL only, and only ever with ink sitting on top. */
  --signal: #00722f;
  --signal-bright: #00c853;
  --signal-wash: #e8f3ea;
  --alert: #b3200c;
  --alert-wash: #fbeae7;
  --warn: #8a5a00;
  --warn-wash: #fdf3df;

  --header-height: 54px;
  --nav-height: 66px;
  --gutter: 18px;

  --tap: 100ms cubic-bezier(0.2, 0, 0.1, 1);

  --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");

  font-family: "Archivo", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  font-variant-numeric: tabular-nums lining-nums;
  font-synthesis: none;
}

/* Money and counts. The width axis does the work a smaller font-size would
   otherwise have to do. */
.caixa-running-total strong,
.sale-dock-inner strong,
.product-price,
.hero-number,
.metric-value,
.money-chip,
.report-money,
.running-head strong,
.table-tile strong {
  font-variant-numeric: tabular-nums lining-nums;
  font-stretch: 88%;
  letter-spacing: -0.015em;
}

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  min-width: 320px;
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Nothing on a till screen should be selectable by a stray long-press - a blue
   selection highlight across a product name is a browser tell. Inputs opt back
   in explicitly. */
body {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
input,
textarea,
[contenteditable] {
  -webkit-user-select: text;
  user-select: text;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
/* -webkit-tap-highlight-color is INHERITED, so setting it only on buttons and
   links leaves Android's blue flash on every other tappable thing - and this
   app delegates clicks from rows, tiles and cards. Set it at the root and it
   is gone everywhere. Measured before the fix: rgba(51, 181, 229, 0.4). */
html,
body,
button,
a {
  -webkit-tap-highlight-color: transparent;
}
button {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
}
/* Any layout rule with a `display` value silently defeats the [hidden]
   attribute, because an author declaration outranks the UA sheet. Every
   conditionally-rendered control in this app is hidden that way, so this line
   is load-bearing: without it the search clear button sits there permanently
   on an empty field. */
[hidden] {
  display: none !important;
}
a {
  color: inherit;
  text-decoration: none;
}

/* Focus is a hard ink outline, never the browser's blue halo, and only for
   keyboard users - a focus ring flashing under a thumb is a tell. */
:focus {
  outline: none;
}
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* A 15px grey OS scrollbar down the side of a phone screen is one of the
   loudest "this is a web page" signals there is. */
*::-webkit-scrollbar {
  width: 0;
  height: 0;
}
* {
  scrollbar-width: none;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.svg-defs {
  position: absolute;
  width: 0;
  height: 0;
}

/* ----------------------------------------------------------------- shell */
.app-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  height: var(--app-height, 100dvh);
  overflow: hidden;
  background: var(--paper);
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  height: calc(var(--header-height) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) var(--gutter) 0;
  background: var(--ink);
  color: var(--ink-inverse);
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 9px;
}
.brand-mark {
  display: block;
  width: 26px;
  height: 26px;
  border-radius: 6px;
}
.wordmark-text {
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

.business-switcher {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 58%;
  padding: 5px 0;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ink-inverse);
  border-bottom: 1px solid var(--rule-inverse);
  transition: border-color var(--tap);
}
.business-switcher:active {
  border-bottom-color: var(--ink-inverse);
}
.business-switcher > span {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis; /* a business NAME, not a number - safe to clip */
}
.business-switcher svg {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The install prompt is a single slim strip. On the previous build it was a
   three-line card that ate 150px of the most valuable screen in the app. */
.install-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex: 0 0 auto;
  padding: 9px var(--gutter);
  background: var(--signal-wash);
  border-bottom: 1px solid var(--rule);
}
.install-banner[hidden] {
  display: none;
}
.install-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.install-brand .brand-mark {
  width: 20px;
  height: 20px;
  border-radius: 5px;
}
.install-brand strong {
  font-size: 0.84rem;
  font-weight: 700;
}
.install-brand p {
  display: none; /* the strap line is on the login screen; here it is noise */
}
.install-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.text-button {
  padding: 7px 10px;
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--signal);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.icon-button {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  color: var(--ink-2);
}
.icon-button svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}
.icon-button:active {
  background: rgba(10, 10, 10, 0.08);
}

.view-stack {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.view {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 0 calc(var(--nav-height) + env(safe-area-inset-bottom) + 12px);
}
.view[hidden] {
  display: none;
}

/* ------------------------------------------------------------ bottom nav */
.bottom-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  flex: 0 0 auto;
  height: calc(var(--nav-height) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--ink);
}
.nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: var(--nav-height);
  color: rgba(250, 249, 245, 0.55);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: color var(--tap), background var(--tap);
}
.nav-item svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-item:active {
  background: rgba(250, 249, 245, 0.1);
}
/* The active tab is a filled block, not a tinted label - at arm's length in
   sunlight a colour difference disappears and a filled shape does not. */
.nav-item.is-active {
  color: var(--ink);
  background: var(--signal-bright);
}

/* --------------------------------------------------------- caixa: header */
.caixa-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 14px var(--gutter) 10px;
}
.caixa-heading h1 {
  margin: 0;
  font-size: 1.14rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.eyebrow {
  margin: 0 0 1px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.caixa-products-link {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink-2);
  border-bottom: 1.5px solid var(--rule-strong);
  padding-bottom: 1px;
}
.caixa-products-link:active {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* THE INSTRUMENT HEAD. One ink panel carrying the day's takings at display
   size, the mode switch, and the close-day control - restructured from a flat
   row of three unrelated things into a hierarchy with one obvious subject. */
.caixa-control-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "total close"
    "mode  mode";
  gap: 14px 12px;
  margin: 0 var(--gutter);
  padding: 16px 16px 14px;
  background: var(--ink);
  color: var(--ink-inverse);
}
.caixa-running-total {
  grid-area: total;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
  color: inherit;
  text-align: left;
}
.total-label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.6);
}
.caixa-running-total strong {
  display: block;
  max-width: 100%;
  margin: 1px 0 2px;
  font-size: 2.7rem;
  font-weight: 800;
  line-height: 0.98;
  color: var(--signal-bright);
  /* No ellipsis and no nowrap: an unusually large total wraps to a second
     line rather than losing a digit. The width axis buys the headroom that
     makes wrapping rare in the first place. */
  font-stretch: 84%;
}
.caixa-running-total small {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.62);
}
.caixa-running-total:active strong {
  color: #fff;
}

.caixa-close-control {
  grid-area: close;
  align-self: start;
  padding: 6px 0 6px 12px;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--ink-inverse);
  border-bottom: 1.5px solid var(--rule-inverse);
  white-space: nowrap;
}
.caixa-close-control:active {
  border-bottom-color: var(--ink-inverse);
}
.caixa-close-control.is-closed {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--signal-bright);
  border-bottom-color: transparent;
}

/* Segmented control drawn as two hard blocks inside the ink panel. */
.caixa-mode {
  grid-area: mode;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1.5px solid var(--rule-inverse);
}
.caixa-mode button {
  padding: 11px 8px;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: rgba(250, 249, 245, 0.72);
  transition: background var(--tap), color var(--tap);
}
.caixa-mode button + button {
  border-left: 1.5px solid var(--rule-inverse);
}
.caixa-mode button.is-active {
  background: var(--ink-inverse);
  color: var(--ink);
}
.caixa-mode button:not(.is-active):active {
  background: rgba(250, 249, 245, 0.12);
}

/* ------------------------------------------------- caixa: find and filter */
.product-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 18px var(--gutter) 0;
  border-bottom: 1.5px solid var(--rule-strong);
  transition: border-color var(--tap);
}
.product-search::before {
  content: "";
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin-right: 10px;
  background: var(--ink-3);
  -webkit-mask: var(--icon-search) center / contain no-repeat;
  mask: var(--icon-search) center / contain no-repeat;
}
.product-search input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 0;
  font-size: 0.98rem;
  font-weight: 600;
  background: none;
  border: 0;
  appearance: none;
}
.product-search input::placeholder {
  color: var(--ink-3);
  font-weight: 500;
}
.product-search input::-webkit-search-cancel-button,
.product-search input::-webkit-search-decoration {
  display: none; /* the OS clear button is a different shape on every device */
  appearance: none;
}
.product-search:focus-within {
  border-bottom-color: var(--ink);
}
.product-search button {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink-3);
}

/* Filters are TABS with an ink underline, not a row of equally loud pills.
   The strip runs edge to edge and scrolls, so a half-visible label at the
   right reads as "there is more" rather than as a clipping bug. */
.category-strip {
  display: flex;
  gap: 22px;
  margin-top: 14px;
  padding: 0 var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  border-bottom: 1px solid var(--rule);
}
.category-chip {
  flex: 0 0 auto;
  padding: 9px 0 10px;
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--ink-3);
  border-bottom: 2.5px solid transparent;
  scroll-snap-align: start;
  transition: color var(--tap), border-color var(--tap);
}
.category-chip.is-active {
  color: var(--ink);
  border-bottom-color: var(--ink);
}

/* ---------------------------------------------------- caixa: product rows */
.product-grid {
  display: block;
  padding: 0 var(--gutter);
}
.product-tile {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-bottom: 1px solid var(--rule);
  transition: background var(--tap);
}
.product-tile:last-child {
  border-bottom: 0;
}
.product-tile:active {
  background: rgba(10, 10, 10, 0.055);
}

.product-add {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  grid-template-areas:
    "art name  price"
    "art stock price";
  align-items: center;
  column-gap: 12px;
  width: 100%;
  min-height: 58px;
  padding: 9px 0;
  text-align: left;
}

/* Product identity is TYPOGRAPHIC here: an ink-ruled initial, not an emoji.
   Emoji are drawn by the operating system, so the same product looks different
   on every phone - which reads as a placeholder rather than as a decision. */
.product-emoji {
  grid-area: art;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  font-size: 1.02rem;
  font-weight: 800;
  font-stretch: 84%;
  color: var(--ink-2);
  border: 1.5px solid var(--rule-strong);
}
.product-emoji.is-art svg {
  width: 24px;
  height: 30px;
}

.product-name {
  grid-area: name;
  align-self: end;
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.2;
}
.product-meta {
  display: contents;
}
.product-price {
  grid-area: price;
  align-self: center;
  padding-left: 10px;
  font-size: 1.06rem;
  font-weight: 800;
  text-align: right;
  white-space: nowrap;
}
.product-stock {
  grid-area: stock;
  align-self: start;
  margin-top: 2px;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--ink-3);
}
.product-stock.is-danger {
  color: var(--alert);
}
.product-action {
  display: none; /* the row's own affordance is enough; this repeated the CTA */
}

.product-tile.is-selected {
  background: var(--signal-wash);
  box-shadow: inset 3px 0 0 var(--signal);
}
.product-tile.is-selected .product-emoji {
  border-color: var(--signal);
  color: var(--signal);
}
.product-tile.has-warning .product-emoji {
  border-color: var(--alert);
}

.quantity-badge {
  display: none; /* the stepper already states the quantity; twice was clutter */
}

/* Stepper: two hard ink squares with the count between them. 40px targets in
   a 62px row, which keeps the whole row comfortably thumb-sized. */
.tile-stepper {
  display: flex;
  align-items: stretch;
  justify-self: end;
  margin: 0 0 12px;
  border: 1.5px solid var(--ink);
}
.tile-stepper button {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  font-size: 1.24rem;
  font-weight: 700;
  line-height: 1;
  transition: background var(--tap), color var(--tap);
}
.tile-stepper button:active {
  background: var(--ink);
  color: var(--ink-inverse);
}
.tile-stepper span {
  display: grid;
  place-items: center;
  min-width: 32px;
  padding: 0 2px;
  font-size: 1.02rem;
  font-weight: 800;
  border-left: 1.5px solid var(--ink);
  border-right: 1.5px solid var(--ink);
}

/* ------------------------------------------------------------ caixa: dock */
.sale-dock {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--nav-height) + env(safe-area-inset-bottom));
  z-index: 6;
  background: var(--ink);
  animation: dock-rise 160ms cubic-bezier(0.2, 0, 0.1, 1);
}
@keyframes dock-rise {
  from {
    transform: translateY(100%);
  }
}
.sale-dock[hidden] {
  display: none;
}
.sale-dock-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px var(--gutter);
}
.sale-dock-inner > div {
  min-width: 0;
}
.sale-dock-inner strong {
  display: block;
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1.05;
  color: var(--ink-inverse);
}
.sale-dock-inner small {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.6);
}
.sale-dock .primary-button {
  flex: 0 0 auto;
  min-width: 132px;
  min-height: 52px;
  padding: 0 22px;
  background: var(--signal-bright);
  color: var(--ink);
}
.view.has-sale-dock {
  padding-bottom: calc(var(--nav-height) + 92px + env(safe-area-inset-bottom));
}

/* ---------------------------------------------------------- caixa: tables */
.tables-intro {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  padding: 20px var(--gutter) 12px;
}
.tables-intro h2 {
  margin: 0;
  font-size: 1.06rem;
  font-weight: 800;
}
.tables-intro p {
  margin: 3px 0 0;
  font-size: 0.82rem;
  color: var(--ink-3);
}
.tables-intro > span {
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.tables-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  margin: 0 var(--gutter);
  background: var(--rule-strong);
  border: 1px solid var(--rule-strong);
}
.table-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 15px 14px;
  background: var(--paper);
  text-align: left;
  transition: background var(--tap);
}
.table-tile:active {
  background: rgba(10, 10, 10, 0.06);
}
.table-number {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.table-tile strong {
  font-size: 1.2rem;
  font-weight: 800;
}
.table-tile small {
  font-size: 0.76rem;
  color: var(--ink-3);
}
.table-tile.is-open {
  background: var(--ink);
  color: var(--ink-inverse);
}
.table-tile.is-open .table-number,
.table-tile.is-open small {
  color: rgba(250, 249, 245, 0.62);
}
.table-tile.is-open strong {
  color: var(--signal-bright);
}

.running-bill {
  margin: 16px var(--gutter) 0;
  border: 1.5px solid var(--ink);
}
.running-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--ink);
  color: var(--ink-inverse);
}
.running-head p {
  margin: 0 0 2px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.62);
}
.running-head h2 {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 800;
}
.running-head strong {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--signal-bright);
}
.bill-lines {
  margin: 0;
  padding: 0;
  list-style: none;
}
.bill-lines li + li {
  border-top: 1px solid var(--rule);
}
.bill-lines button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 12px 16px;
  text-align: left;
}
.bill-lines button:active {
  background: rgba(10, 10, 10, 0.055);
}
.bill-lines span {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.bill-lines strong {
  font-size: 0.94rem;
  font-weight: 700;
}
.bill-lines small {
  font-size: 0.74rem;
  color: var(--ink-3);
}
.bill-empty {
  margin: 0;
  padding: 20px 16px;
  font-size: 0.88rem;
  color: var(--ink-3);
  text-align: center;
}
.table-actions {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  padding: 12px 16px 14px;
  border-top: 1px solid var(--rule);
}

/* ------------------------------------------------------------- primitives */
.primary-button {
  display: inline-grid;
  place-items: center;
  min-height: 52px;
  padding: 0 20px;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--ink-inverse);
  background: var(--ink);
  transition: transform 70ms ease, opacity var(--tap);
}
.primary-button:active {
  transform: translateY(1px);
  opacity: 0.9;
}
.primary-button[disabled] {
  background: rgba(10, 10, 10, 0.16);
  color: rgba(10, 10, 10, 0.45);
  cursor: default;
}
.wide-button {
  width: 100%;
}
.secondary-button,
.quiet-button {
  display: inline-grid;
  place-items: center;
  min-height: 52px;
  padding: 0 18px;
  font-size: 0.94rem;
  font-weight: 700;
  color: var(--ink);
  border: 1.5px solid var(--ink);
  background: transparent;
}
.secondary-button:active,
.quiet-button:active {
  background: rgba(10, 10, 10, 0.08);
}
.danger-button {
  display: inline-grid;
  place-items: center;
  min-height: 52px;
  padding: 0 18px;
  font-weight: 700;
  color: #fff;
  background: var(--alert);
}
.link-button {
  padding-bottom: 1px;
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1.5px solid var(--rule-strong);
}
.button-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.back-button,
.login-back,
.sector-back,
.resumo-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 0;
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--ink-2);
}

.empty-state {
  margin: 22px var(--gutter);
  padding: 26px 18px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink-3);
  text-align: center;
  border: 1.5px dashed var(--rule-strong);
}

/* ---------------------------------------------------------------- sheets */
.sheet-layer {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.sheet-layer[hidden] {
  display: none;
}
.sheet-backdrop {
  position: absolute;
  inset: 0;
  width: 100%;
  background: rgba(10, 10, 10, 0.44);
  animation: fade-in 140ms ease;
}
@keyframes fade-in {
  from {
    opacity: 0;
  }
}
.bottom-sheet {
  position: relative;
  max-height: 90dvh;
  overflow-y: auto;
  padding: 8px var(--gutter) calc(20px + env(safe-area-inset-bottom));
  background: var(--paper);
  border-top: 3px solid var(--ink);
  animation: sheet-up 200ms cubic-bezier(0.2, 0, 0.1, 1);
}
@keyframes sheet-up {
  from {
    transform: translateY(14%);
  }
}
.sheet-handle {
  width: 44px;
  height: 3px;
  margin: 6px auto 12px;
  background: var(--rule-strong);
}
.sheet-header {
  margin-bottom: 14px;
}
.sheet-header h2 {
  margin: 0;
  font-size: 1.24rem;
  font-weight: 800;
  letter-spacing: -0.015em;
}
.sheet-header p,
.sheet-note {
  margin: 6px 0 0;
  font-size: 0.88rem;
  color: var(--ink-2);
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-height) + 22px + env(safe-area-inset-bottom));
  z-index: 60;
  transform: translateX(-50%);
  max-width: calc(100% - 32px);
  padding: 13px 18px;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--ink-inverse);
  background: var(--ink);
  animation: toast-in 180ms cubic-bezier(0.2, 0, 0.1, 1);
}
.toast[hidden] {
  display: none;
}
@keyframes toast-in {
  from {
    opacity: 0;
    transform: translate(-50%, 10px);
  }
}

/* --------------------------------------------------- generic screen layer
   Every other screen inherits this coherent baseline until its own pass
   lands. Nothing here is white-card-on-grey: the system is paper, hairline
   and ink throughout. */
.page-intro,
.home-intro,
.subscreen-header,
.session-intro,
.section-heading {
  padding: 18px var(--gutter) 10px;
}
h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.12;
}
h2 {
  font-size: 1.08rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}
p {
  line-height: 1.45;
}
.subtle,
.field-hint,
.section-note {
  color: var(--ink-3);
  font-size: 0.85rem;
}

.paper-card,
.management-card,
.profile-card,
.analysis-card,
.settlement-card,
.nudge-card,
.delivery-card,
.phone-card,
.login-card,
.section-block,
.management-block,
.analysis-block {
  padding: 16px;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}

.hero-card {
  margin: 0 var(--gutter);
  padding: 18px;
  background: var(--ink);
  color: var(--ink-inverse);
}
.hero-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.62);
}
.hero-number {
  display: block;
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1.05;
  color: var(--signal-bright);
}

.field label,
.login-label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field input,
.field select,
.field textarea,
.login-input {
  width: 100%;
  padding: 13px 12px;
  font-size: 1rem;
  font-weight: 600;
  background: var(--paper-raised);
  border: 1.5px solid var(--rule-strong);
  appearance: none;
}
.field input:focus,
.login-input:focus {
  border-color: var(--ink);
  outline: none;
}
.code-input {
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: 0.34em;
  text-align: center;
}
.field-error {
  min-height: 1em;
  margin: 6px 0 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--alert);
}

.status-badge {
  display: inline-block;
  padding: 4px 8px;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-inverse);
  background: var(--ink);
}
.status-badge.is-ok {
  background: var(--signal);
}
.status-badge.is-danger {
  background: var(--alert);
}

.login-view {
  padding: 0;
}
.login-screen {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  padding-bottom: 30px;
  background: var(--paper);
}
.login-brand {
  padding: 40px var(--gutter) 26px;
  text-align: center;
}
.login-mark {
  /* The mark is display:block, so text-align on the parent does not centre it.
     Two auto margins do. */
  width: 58px;
  height: 58px;
  margin-inline: auto;
  border-radius: 13px;
}
.login-wordmark {
  margin: 14px 0 4px;
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}
.login-brand > p:last-child {
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink-3);
}
.login-card {
  margin: 0 var(--gutter);
  padding: 20px 18px 22px;
}
.login-copy {
  margin: 6px 0 16px;
  color: var(--ink-2);
}
.demo-hint {
  font-size: 0.82rem;
  color: var(--ink-3);
}
.demo-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 16px;
  padding: 10px 12px;
  font-size: 0.82rem;
  color: var(--ink-2);
  background: var(--warn-wash);
  border-left: 3px solid var(--warn);
}
.demo-notice p {
  margin: 0;
}

/* Inline icons standing in for characters the bundled face does not contain
   (see tools/fix-symbol-glyphs.py). Sized in em so they track the type around
   them instead of drifting when a label changes size. */
.ui-icon {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.12em;
}
.management-icon,
.nudge-icon,
.settlement-icon,
.profile-link-icon,
.post-close-check,
.closed-state > span:first-child,
.delivery-symbol {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  font-size: 1.05rem;
  color: var(--ink);
  border: 1.5px solid var(--rule-strong);
}
.post-close-check,
.closed-state > span:first-child {
  color: var(--signal);
  border-color: var(--signal);
}
.closed-state {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 var(--gutter);
  padding: 14px 16px;
  background: var(--signal-wash);
  border-left: 3px solid var(--signal);
}
.closed-state strong {
  font-weight: 800;
}
.closed-state p {
  margin: 2px 0 0;
  font-size: 0.84rem;
  color: var(--ink-2);
}
.status-badge.is-ok {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* Dismiss controls. Both of these render as a bare "x" character, which gives
   the button the width of the glyph - measured at 8x15 before this rule. */
.nudge-dismiss,
.demo-notice button {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  margin: -8px -10px -8px 0;
  font-size: 1.15rem;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-3);
}
.nudge-dismiss:active,
.demo-notice button:active {
  color: var(--ink);
  background: rgba(10, 10, 10, 0.08);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Suppressed rather than removed: the element stays in the DOM (and in the
   install flow) but never occupies the selling screen. See
   syncInstallBannerVisibility in app.js. */
.install-banner.is-suppressed {
  display: none !important;
}

/* ==========================================================================
   MANAGEMENT SCREENS - variant A
   --------------------------------------------------------------------------
   Same instrument logic as Caixa, applied to the screens behind it: numbers
   live in inverted panels, everything else is a hairline matrix. There is not
   one rounded card or one shadow in this section, because there is not one in
   the rest of the system either.
   ========================================================================== */

.section-block {
  margin-top: 26px;
  padding: 0;
  background: none;
  border: 0;
}
.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 0 var(--gutter) 8px;
}
.section-heading h2 {
  margin: 0;
}
.section-note {
  flex: 0 0 auto;
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-3);
}

/* -------------------------------------------------------- the value banner
   The one number the owner opens the app for. Inverted panel, condensed
   figure, and the two switches drawn as hairline matrices above it. */
.metric-banner {
  margin: 0 var(--gutter);
  padding: 0;
  background: var(--ink);
  color: var(--ink-inverse);
  border: 1.5px solid var(--ink);
}
.metric-periods,
.metric-tabs,
.report-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.metric-periods button,
.metric-tabs button,
.report-tabs button {
  padding: 11px 6px;
  font-size: 0.82rem;
  font-weight: 700;
  color: rgba(250, 249, 245, 0.62);
  border-bottom: 1px solid var(--rule-inverse);
  transition: background var(--tap), color var(--tap);
}
.metric-periods button + button,
.metric-tabs button + button,
.report-tabs button + button {
  border-left: 1px solid var(--rule-inverse);
}
.metric-periods button.is-active,
.metric-tabs button.is-active,
.report-tabs button.is-active {
  color: var(--ink);
  background: var(--ink-inverse);
}
.metric-tabs button {
  font-size: 0.86rem;
}
.metric-value {
  padding: 18px 18px 16px;
}
.metric-value p {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(250, 249, 245, 0.62);
}
.metric-value strong {
  display: block;
  margin: 3px 0 4px;
  font-size: 2.5rem;
  font-weight: 800;
  font-stretch: 84%;
  line-height: 1;
  color: var(--signal-bright);
}
.metric-value strong.is-negative {
  color: #ff6b4a;
}
.metric-value small {
  font-size: 0.78rem;
  color: rgba(250, 249, 245, 0.66);
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--rule-inverse);
  border-top: 1px solid var(--rule-inverse);
}
.money-chip {
  flex: 1 1 44%;
  padding: 9px 12px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-inverse);
  background: var(--ink);
}

/* --------------------------------------------------------------- the grid
   Six destinations as a hairline matrix - the one place in the app where a
   grid of equal things is the honest shape. */
.management-block {
  margin-top: 26px;
}
.management-menu {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  margin: 0 var(--gutter);
  background: var(--rule-strong);
  border: 1px solid var(--rule-strong);
}
.management-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 16px 14px;
  text-align: left;
  background: var(--paper);
  transition: background var(--tap);
}
.management-card:active {
  background: rgba(10, 10, 10, 0.07);
}
.management-card strong {
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.2;
}

/* ------------------------------------------------------------- list rows
   Every label/value pair in the app resolves to one shape: label left, number
   right, hairline between. Money sets tabular so the column reads as a column.
   Deliberately no truncation anywhere in here (CONV-144) - a long product
   name wraps and the row grows. */
.paper-card,
.alert-list,
.summary-list,
.stock-list,
.expense-list,
.day-sales-list,
.ranking-list,
.result-lines,
.team-list,
.settlement-list,
.person-summary-list {
  margin: 0 var(--gutter);
  padding: 0;
  list-style: none;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.summary-row,
.alert-row,
.stock-row,
.expense-row,
.result-line,
.day-sales-list li,
.ranking-list li,
.person-summary-list li,
.team-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
}
.summary-row:last-child,
.alert-row:last-child,
.stock-row:last-child,
.expense-row:last-child,
.result-line:last-child,
.day-sales-list li:last-child,
.ranking-list li:last-child,
.person-summary-list li:last-child,
.team-list li:last-child {
  border-bottom: 0;
}
.summary-row span,
.expense-main,
.stock-main,
.day-sale-main,
.team-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.summary-row strong,
.result-line strong,
.stock-row strong,
.expense-row strong,
.day-sale-main strong {
  font-size: 0.94rem;
  font-weight: 700;
}
.summary-row small,
.expense-main small,
.stock-main small,
.day-sale-main small,
.subtle {
  font-size: 0.78rem;
  color: var(--ink-3);
}
.money-column,
.stock-numbers {
  flex: 0 0 auto;
  font-size: 1rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-stretch: 88%;
  text-align: right;
  white-space: nowrap;
}
.result-line span:first-child {
  font-size: 0.92rem;
  color: var(--ink-2);
}
.result-line strong {
  font-size: 1.02rem;
  font-variant-numeric: tabular-nums;
  font-stretch: 88%;
}

/* The hero result of a day, in the same inverted panel as the day's takings. */
.hero-card {
  display: block;
}
.hero-meta {
  display: block;
  margin-top: 2px;
  font-size: 0.78rem;
  color: rgba(250, 249, 245, 0.66);
}
.result-lines {
  margin: 14px 0 0;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--rule-inverse);
}
.hero-card .result-line {
  padding: 9px 0;
  border-bottom: 1px solid var(--rule-inverse);
}
.hero-card .result-line span:first-child {
  color: rgba(250, 249, 245, 0.72);
}
.hero-card .result-line strong {
  color: var(--ink-inverse);
}

/* ------------------------------------------------------------ prompt cards
   A nudge is information plus one action. Ink rule on the left so it reads as
   an aside, never as an alert the merchant has to clear. */
.home-nudges {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 4px var(--gutter) 0;
}
.nudge-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) 40px;
  grid-template-areas:
    "icon body   close"
    "icon action action";
  align-items: start;
  gap: 4px 12px;
  padding: 12px 12px 12px 14px;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
}
.nudge-icon {
  grid-area: icon;
}
.nudge-card > div:not(.nudge-actions) {
  grid-area: body;
}
.nudge-card.is-week {
  border-left-color: var(--signal);
}
.nudge-card strong {
  font-size: 0.94rem;
  font-weight: 700;
}
.nudge-card p {
  margin: 2px 0 0;
  font-size: 0.8rem;
  color: var(--ink-3);
}
.nudge-dismiss {
  grid-area: close;
  justify-self: end;
  margin: -6px -6px 0 0;
}
.nudge-link {
  grid-area: action;
  justify-self: start;
  padding: 7px 0 0;
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1.5px solid var(--rule-strong);
}
.nudge-actions {
  grid-area: action;
  display: flex;
  gap: 18px;
}

.settlement-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  border-bottom: 1px solid var(--rule);
}
.settlement-card:last-child {
  border-bottom: 0;
}
.settlement-card strong {
  font-size: 0.92rem;
}
.settlement-card p {
  margin: 3px 0 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--ink-3);
}

.alert-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  background: var(--warn);
}
.alert-row .status-badge.is-danger ~ .alert-dot,
.alert-row:has(.is-danger) .alert-dot {
  background: var(--alert);
}

.delivery-card {
  margin: 0 var(--gutter);
  padding: 16px;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.delivery-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.delivery-head h2 {
  margin: 0;
  font-size: 1rem;
}
.delivery-head p {
  margin: 2px 0 0;
  font-size: 0.8rem;
  color: var(--ink-3);
}
.delivery-confirmed {
  padding: 11px;
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--signal);
  text-align: center;
  background: var(--signal-wash);
}

/* -------------------------------------------------------- the date stepper */
.date-stepper {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  margin: 0 var(--gutter) 14px;
  border: 1.5px solid var(--ink);
}
.date-stepper button {
  display: grid;
  place-items: center;
  height: 44px;
  font-size: 1.3rem;
  font-weight: 700;
  transition: background var(--tap), color var(--tap);
}
.date-stepper button:active {
  background: var(--ink);
  color: var(--ink-inverse);
}
.date-stepper button[disabled] {
  color: rgba(10, 10, 10, 0.24);
  cursor: default;
}
.date-stepper strong {
  padding: 0 6px;
  font-size: 0.92rem;
  font-weight: 700;
  text-align: center;
  border-left: 1.5px solid var(--ink);
  border-right: 1.5px solid var(--ink);
  align-self: stretch;
  display: grid;
  place-items: center;
}

/* ----------------------------------------------- actions at the foot of a screen */
.close-action,
.reopen-action,
.expense-day-link,
.stock-count-action,
.resumo-action,
.session-actions > * {
  margin: 18px var(--gutter) 0;
  width: calc(100% - 2 * var(--gutter));
}
.session-actions {
  display: flex;
  flex-direction: column;
}
.button-pair {
  margin: 0 var(--gutter);
}

/* --------------------------------------------------------- products screen */
.product-list {
  margin: 0 var(--gutter);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.product-row {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  text-align: left;
  border-bottom: 1px solid var(--rule);
  transition: background var(--tap);
}
.product-row:last-child {
  border-bottom: 0;
}
.product-row:active {
  background: rgba(10, 10, 10, 0.055);
}
.product-row-emoji {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  font-size: 1rem;
  font-weight: 800;
  font-stretch: 84%;
  color: var(--ink-2);
  border: 1.5px solid var(--rule-strong);
}
.product-row-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.product-row-main strong {
  font-size: 0.95rem;
  font-weight: 700;
}
/* Deliberately allowed to wrap. Round 9 of the base app fixed this exact line
   with text-overflow: ellipsis and clipped every row to "custo ...", on a
   screen titled "Precos, custos e stock" (CONV-144). */
.product-row-main small {
  font-size: 0.76rem;
  line-height: 1.35;
  color: var(--ink-3);
}
.product-row-stock {
  flex: 0 0 auto;
  font-size: 0.82rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* ------------------------------------------------------------ stock screen */
.stock-category,
.stock-count-category {
  margin-top: 20px;
}
.stock-category-title {
  padding: 0 var(--gutter) 8px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.stock-numbers {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.stock-count-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
}
.stock-count-inputs input {
  width: 100%;
  padding: 10px;
  font-size: 1rem;
  font-weight: 700;
  text-align: center;
  border: 1.5px solid var(--rule-strong);
}
.stock-count-progress,
.stock-count-totals {
  margin: 0 var(--gutter);
  padding: 12px 14px;
  font-size: 0.86rem;
  background: var(--signal-wash);
  border-left: 3px solid var(--signal);
}

/* ------------------------------------------------------- reports + ranking */
.report-tabs {
  margin: 0 var(--gutter) 14px;
  background: var(--ink);
  border: 1.5px solid var(--ink);
}
.report-date strong {
  font-size: 0.9rem;
}
.bar-track {
  position: relative;
  height: 6px;
  margin-top: 6px;
  background: var(--rule);
}
.bar-track > span {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--ink);
}
.category-bars li {
  display: block;
  padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
}

/* --------------------------------------------------------------- profile */
.profile-card,
.profile-link-card {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 var(--gutter) 10px;
  padding: 16px;
  width: calc(100% - 2 * var(--gutter));
  text-align: left;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.profile-avatar,
.team-avatar,
.profile-pick-avatar,
.business-initial {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--ink-inverse);
  background: var(--ink);
}
.row-chevron {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--ink-3);
}
.profile-setting,
.setting-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

/* ------------------------------------------------------------ sheet forms */
.form-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.field {
  display: block;
}
.payment-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--rule-strong);
  border: 1px solid var(--rule-strong);
}
.payment-button {
  padding: 15px 10px;
  font-size: 0.94rem;
  font-weight: 700;
  background: var(--paper-raised);
  transition: background var(--tap), color var(--tap);
}
.payment-button:active,
.payment-button.is-active {
  color: var(--ink-inverse);
  background: var(--ink);
}
.segmented {
  display: grid;
  grid-auto-flow: column;
  border: 1.5px solid var(--ink);
}
.segmented button {
  padding: 11px 8px;
  font-size: 0.88rem;
  font-weight: 700;
}
.segmented button + button {
  border-left: 1.5px solid var(--ink);
}
.segmented button.is-active {
  color: var(--ink-inverse);
  background: var(--ink);
}
.sector-choices,
.emoji-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--rule-strong);
  border: 1px solid var(--rule-strong);
}
.emoji-picker {
  grid-template-columns: repeat(6, 1fr);
}
.sector-choice,
.emoji-choice {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 12px;
  font-size: 0.92rem;
  font-weight: 700;
  text-align: left;
  background: var(--paper-raised);
}
.emoji-choice {
  justify-content: center;
  padding: 12px 0;
  font-size: 1.2rem;
}
.sector-choice:active,
.emoji-choice:active,
.emoji-choice.is-active {
  color: var(--ink-inverse);
  background: var(--ink);
}
.business-list {
  display: flex;
  flex-direction: column;
}
.business-row,
.business-choice {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 13px 0;
  text-align: left;
  border-bottom: 1px solid var(--rule);
}
.profile-pick {
  display: flex;
  flex-direction: column;
}
.profile-pick button {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 0;
  text-align: left;
  border-bottom: 1px solid var(--rule);
}
.profile-pick span:not(.profile-pick-avatar) {
  display: flex;
  flex-direction: column;
}
.profile-pick small {
  font-size: 0.78rem;
  color: var(--ink-3);
}
.onboarding-list {
  margin: 16px 0;
  padding: 0;
  list-style: none;
}
.onboarding-list li {
  display: flex;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--rule);
}
.onboarding-list span {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  font-size: 0.82rem;
  font-weight: 800;
  color: var(--ink-inverse);
  background: var(--ink);
}
.onboarding-list strong {
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.35;
}

/* Stock rows carry a name, a margin line, sometimes a badge, and THREE
   figures. Laid out as one flex row the figures took the width and the name
   wrapped to two lines with the badge stranded beneath it. The figures stack
   right-aligned instead: the name keeps the room, the numbers keep a column,
   and nothing is truncated to make it fit (CONV-144). */
.stock-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  text-align: left;
}
.stock-main {
  align-items: flex-start;
}
.stock-main .status-badge {
  margin-top: 5px;
}
.stock-numbers {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
.stock-numbers strong {
  font-size: 1rem;
  font-weight: 800;
  font-stretch: 88%;
}
.stock-numbers small {
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--ink-3);
  white-space: nowrap;
}
.stock-row.is-low .stock-numbers strong {
  color: var(--alert);
}

/* A full-width action sitting directly on a screen still needs the gutter -
   without it the button ran past both edges of everything around it. */
.view > .wide-button {
  width: calc(100% - 2 * var(--gutter));
  margin: 10px var(--gutter) 0;
}
.button-pair.section-block {
  margin-top: 12px;
}

/* -------------------------------------------------------- reports, properly
   Three shapes here that the generic row rule gets wrong, because each one is
   a container rather than a row: the money card, the ranking (name + value,
   then a bar beneath) and the category bars. */
.report-money {
  margin: 0 var(--gutter);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.report-money > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--rule);
}
.report-money > div:last-child {
  border-bottom: 0;
}
.report-money span {
  font-size: 0.92rem;
  color: var(--ink-2);
}
.report-money strong {
  font-size: 1.02rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-stretch: 88%;
  white-space: nowrap;
}
.report-money .is-total {
  color: var(--ink-inverse);
  background: var(--ink);
}
.report-money .is-total span {
  color: rgba(250, 249, 245, 0.72);
}
.report-money .is-total strong {
  font-size: 1.24rem;
  color: var(--signal-bright);
}
.report-money .is-negative {
  color: #ff6b4a;
}

.report-close {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 14px var(--gutter) 0;
  padding: 12px 14px;
  font-size: 0.88rem;
  font-weight: 600;
  border: 1px solid var(--rule);
}
.report-close button {
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1.5px solid var(--rule-strong);
}
.report-close.is-closed {
  color: var(--signal);
  background: var(--signal-wash);
  border-color: transparent;
  border-left: 3px solid var(--signal);
}

.analysis-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.analysis-card {
  margin: 0 var(--gutter);
  padding: 14px 0 4px;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.analysis-card h3 {
  margin: 0 14px 2px;
  font-size: 0.95rem;
  font-weight: 800;
}
.analysis-hint {
  margin: 0 14px 8px;
  font-size: 0.78rem;
  color: var(--ink-3);
}
.analysis-card .empty-state {
  margin: 12px 14px 14px;
}

/* A ranking row is two stacked things, not a label and a value side by side. */
.ranking-list {
  margin: 0;
  border: 0;
  background: none;
}
.ranking-list li {
  display: block;
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
}
.ranking-list li:last-child {
  border-bottom: 0;
}
.ranking-list li > div:first-child {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ranking-list strong {
  font-size: 0.9rem;
  font-weight: 700;
}
.ranking-list span {
  font-size: 0.86rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.category-bars > div {
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
}
.category-bars > div:last-child {
  border-bottom: 0;
}
.category-bars p {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  font-size: 0.9rem;
}
.category-bars span {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ profile, properly
   Five structures the generic layer could not guess: the brand block, the
   phone card, the settings toggle, the link card and the footer. The toggle
   matters most - a native checkbox renders as the OS's own blue control,
   which is one of the loudest "this is a web page" signals on the screen. */
.profile-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 var(--gutter) 16px;
  padding: 14px;
  border: 1px solid var(--rule);
}
.brand-mark-profile {
  width: 40px;
  height: 40px;
  border-radius: 10px;
}
.profile-wordmark {
  margin: 0;
  font-size: 1.24rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}
.brand-tagline {
  margin: 2px 0 0;
  font-size: 0.8rem;
  color: var(--ink-3);
}
.profile-card h2 {
  margin: 0;
  font-size: 1.16rem;
}
.phone-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 0 var(--gutter);
}
.phone-card > span {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.phone-card strong {
  font-size: 1.3rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.phone-card small {
  font-size: 0.8rem;
  color: var(--ink-3);
}
.profile-setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 0 var(--gutter);
  cursor: pointer;
}
.profile-setting > span:first-child {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.profile-setting strong {
  font-size: 0.94rem;
  font-weight: 700;
}
.profile-setting small {
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--ink-3);
}
.setting-switch {
  position: relative;
  flex: 0 0 auto;
  width: 54px;
  height: 32px;
}
.setting-switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.setting-switch > span {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 10, 0.16);
  transition: background var(--tap);
}
.setting-switch > span::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 26px;
  height: 26px;
  background: var(--paper-raised);
  transition: transform 140ms cubic-bezier(0.2, 0, 0.1, 1);
}
.setting-switch input:checked + span {
  background: var(--signal);
}
.setting-switch input:checked + span::after {
  transform: translateX(22px);
}
.profile-link-card {
  display: flex;
  align-items: center;
  gap: 14px;
}
.profile-link-card > span:nth-child(2) {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.profile-link-card strong {
  font-size: 0.96rem;
  font-weight: 700;
}
.profile-link-card small {
  font-size: 0.8rem;
  color: var(--ink-3);
}
.business-row,
.business-choice {
  padding: 13px 14px;
}
.business-list {
  margin: 0 var(--gutter);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
}
.business-row > span:nth-child(2),
.business-choice > span:nth-child(2) {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.business-row small,
.business-choice small {
  font-size: 0.78rem;
  color: var(--ink-3);
}
.business-row .status-badge {
  margin-left: auto;
}
.profile-footer {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  margin: 26px var(--gutter) 0;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}
.demo-profile-note {
  margin: 0;
  font-size: 0.8rem;
  color: var(--ink-3);
}
.link-button.is-danger {
  color: var(--alert);
  border-bottom-color: var(--alert);
}
.team-help,
.session-intro p {
  margin: 0 var(--gutter);
  font-size: 0.86rem;
  color: var(--ink-3);
}
