/* Sofonn design system — components (spec 2026-10-08 §4). Colours only via var(--…). Calm: no glow, no lift,
   80 ms hover, ≤150 ms. States: :hover/.is-hover · :active · :focus-visible · :disabled · .is-selected · .is-error. */

/* ---------- Icon ---------- */
.sf-icon{flex:none;display:inline-block;vertical-align:middle}

/* ---------- Buttons ---------- */
.sf-btn{--h:var(--control-md);--px:16px;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:var(--h);padding:0 var(--px);border-radius:var(--radius-pill);font:var(--ui-button);white-space:nowrap;
  cursor:pointer;border:1px solid transparent;background:transparent;color:var(--text-2);text-decoration:none;
  transition:background var(--dur-hover) var(--ease-standard),border-color var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-btn:hover{text-decoration:none}
.sf-btn-sm{--h:var(--control-sm);--px:12px}
.sf-btn-lg{--h:var(--control-lg);--px:20px}
.sf-btn-icon{width:var(--h);padding:0}
.sf-btn:disabled,.sf-btn.is-disabled{opacity:.38;pointer-events:none}
.sf-btn-primary{background:var(--accent);color:var(--text-on-accent)}
.sf-btn-primary:hover,.sf-btn-primary.is-hover{background:color-mix(in srgb,var(--accent) 88%,var(--text))}
.sf-btn-secondary{border-color:var(--border)}
.sf-btn-secondary:hover,.sf-btn-secondary.is-hover{background:var(--surface-2);color:var(--text)}
.sf-btn-ghost:hover,.sf-btn-ghost.is-hover{background:var(--surface-2);color:var(--text)}
.sf-btn.is-selected{background:var(--highlight);color:var(--accent-text)}
/* Marketing / login hero only (guard allow-list). */
.sf-btn-cta{--h:56px;--px:28px;font-size:16px;background:var(--accent);color:var(--text-on-accent);box-shadow:var(--shadow-e2)}
.sf-kbd{font:var(--ui-meta);padding:2px 6px;border-radius:var(--radius-xs);border:1px solid var(--border);color:var(--text-3);background:var(--surface)}
.sf-btn-primary .sf-kbd{color:var(--text-on-accent);border-color:color-mix(in srgb,var(--text-on-accent) 40%,transparent);background:transparent}

/* ---------- Page header ---------- */
.sf-page-header{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-6)}
.sf-page-header__text{display:flex;flex-direction:column;gap:var(--space-1);min-width:0}
.sf-page-header__actions{display:flex;flex-wrap:wrap;gap:var(--space-2)}
/* The page header sits on the wallpaper, not on glass: its switches, neutral buttons and fields carry the header glass (fill + blur),
   so their words read over any wallpaper in light / dark × clear / tinted (owner 2026-10-15: the Activity Log Capture switch was not
   legible). The selected option and the primary keep their accent. Their own menus open from a separate panel, so a blur here is safe. */
.sf-page-header__actions :is(.sf-segmented,.sf-btn-secondary,.sf-input){background:var(--glass-fill);border-color:var(--glass-border);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
.sf-page-header__actions .sf-segmented__btn:not(.sel,[aria-pressed="true"],[aria-current="page"]),.sf-page-header__actions .sf-segmented__opt input:not(:checked)+span{color:var(--text)}
.sf-page-header__actions>form>.sf-meta,.sf-page-header__actions>.sf-meta{font:var(--ui-label);color:var(--text-2)}   /* a label beside them ("Capture") reads like the subtitle */
/* The page ⓘ (owner 2026-10-22): a round 40 px neutral button centred with the buttons beside it, not a 24 px glyph at the top of the row */
.sf-page-header__actions>.sf-info{align-self:center}
.sf-page-header__actions>.sf-info>summary{display:grid;place-items:center;width:var(--control-md);height:var(--control-md);padding:0;border-radius:50%;border:1px solid var(--glass-border);background:var(--glass-fill);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
.sf-page-header__actions>.sf-info>summary:hover{background:color-mix(in srgb,var(--text) 6%,var(--glass-fill))}
.sf-page-header__meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1) var(--space-3);font:var(--ui-body);color:var(--text-2);font-variant-numeric:tabular-nums}
.sf-page-header__meta b{color:var(--text);font-weight:600}
/* Trail bar (owner 2026-10-19: no title under the breadcrumb): breadcrumb left, the page's actions right on the same row; many
   actions wrap right-aligned under it; on a phone the actions go under the trail. Under a hero only the actions stay, right. */
.sf-page-header--trailed{justify-content:flex-end;align-items:center;margin-bottom:var(--space-4)}
.sf-stack>.sf-page-header--trailed{margin-bottom:0}   /* the stack's gap is the space under the trail row */
.sf-page-header--bar{flex-direction:column;align-items:stretch;gap:var(--space-3)}
.sf-page-header--empty{margin:0}
.sf-page-header__bar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-4);min-height:var(--control-sm)}
.sf-page-header__bar>.sf-breadcrumb{flex:1 1 auto;margin-bottom:0}
.sf-page-header__bar>.sf-page-header__actions{margin-left:auto;justify-content:flex-end}
/* Fleet scope (owner 2026-11-02): fixed left end of the page's top row: ← All vessels + the pinned filter chip */
.sf-fleet-scope{display:inline-flex;align-items:center;gap:var(--space-2);flex:0 0 auto}
.sf-page-header--empty>.sf-fleet-scope{margin-right:auto}   /* under a hero the header row is right-aligned: the scope stays at the left */
.sf-fleet-scope__pin{display:inline-flex;align-items:center;gap:var(--space-1);height:var(--control-sm);padding:0 var(--space-1) 0 var(--space-2);
  border:1px solid var(--border);border-radius:var(--radius-pill);color:var(--text-2);font:var(--ui-label);background:var(--surface)}
.sf-fleet-scope__name{max-width:18ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
.sf-fleet-scope__x{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;cursor:pointer;transition:background 80ms}
.sf-fleet-scope__x:hover,.sf-fleet-scope__x:focus-visible{background:var(--surface-2)}
@media (max-width:767px){.sf-page-header__bar>.sf-page-header__actions{margin-left:0;justify-content:flex-start;width:100%}
  /* a long switch in the header (Engine alerts stages) swipes inside its own strip instead of widening the page (owner 2026-10-22) */
  .sf-page-header__bar{min-width:0;max-width:100%}.sf-page-header__bar>.sf-page-header__actions{min-width:0}
  .sf-page-header__actions>.sf-segmented{max-width:100%;overflow-x:auto;scrollbar-width:none}
  /* one button left (Emissions objectives: Save): it stays at the right end of the breadcrumb line when there is room (owner 2026-10-22) */
  .sf-page-header__bar>.sf-page-header__actions:has(>.sf-btn:only-child){width:auto;margin-left:auto}   /* one BUTTON only: a wider control (Time sheet's day navigator) keeps its own line */
  .sf-page-header__bar:has(>.sf-page-header__actions>.sf-btn:only-child)>.sf-breadcrumb{flex:1 1 0}}   /* a long trail wraps its own words; the button stays on its line (owner 2026-10-22) */
@media print{.sf-page-header--trailed>.sf-sr-only{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto;white-space:normal}}   /* paper has no breadcrumb */

/* ---------- Cards ---------- */
/* = the design system Card (radius 20, padding 24) in EXACTLY the header/sidebar glass (.sf-glass: --glass-fill, --glass-border,
   blur --glass-blur + saturate --glass-saturate, shadow e2), so Clear/Tinted moves header, sidebar and cards together. Owner 2026-10-09. */
.sf-card{position:relative;border-radius:var(--radius-xl);padding:var(--space-6);background:var(--glass-fill);border:1px solid var(--glass-border);box-shadow:var(--shadow-e2);color:var(--text);min-width:0;
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
.sf-card.is-flush{padding:0;overflow:hidden}
.sf-card__head{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-4)}
.sf-card.is-flush>.sf-card__head{padding:var(--space-6) var(--space-6) 0}
.sf-card__titles{display:flex;flex-direction:column;gap:2px;flex:1 0 auto;min-width:0;max-width:100%}   /* the title never squeezes: long actions wrap under it (narrow rail cards) */
.sf-card__actions{display:flex;gap:var(--space-2);flex:none}
.sf-card .sf-card,.sf-card .sf-kpi{box-shadow:none}   /* nested card: lighter tint, no second blur (on its glass layer, see the end of this file) */
/* A card that folds (x-sf.card :fold, 2026-11-05): the head is the summary line (title + what is inside now + arrow), the body opens with
   the Reel expand (Motion block). */
.sf-card.is-fold{padding:0}
.sf-card.is-fold>.sf-card__head{flex-wrap:nowrap;align-items:center;margin:0;padding:var(--space-4) var(--space-6);cursor:pointer;list-style:none;border-radius:inherit}
.sf-card.is-fold>.sf-card__head::-webkit-details-marker{display:none}
.sf-card.is-fold>.sf-card__head>.sf-card__titles{flex:1 1 auto}
.sf-card.is-fold>.sf-card__head:hover .sf-card__arrow{color:var(--text)}
.sf-card__arrow{flex:none;color:var(--text-2)}
.sf-card.is-fold[open]>.sf-card__head>.sf-card__arrow{transform:rotate(90deg)}
.sf-card.is-fold>.sf-card__body{padding:var(--space-4) var(--space-6) var(--space-6);border-top:1px solid var(--divider)}
@media (max-width:639px){.sf-card.is-fold>.sf-card__head{padding:var(--space-4)}.sf-card.is-fold>.sf-card__body{padding:var(--space-4)}}

/* ---------- KPI ---------- */
.sf-kpi{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-6);border-radius:var(--radius-xl);
  background:var(--glass-fill);border:1px solid var(--glass-border);box-shadow:var(--shadow-e2);color:var(--text);min-width:0;
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
a.sf-kpi:hover{text-decoration:none;border-color:var(--border-strong)}
.sf-kpi__label{display:flex;align-items:center;gap:var(--space-2);font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-2)}
.sf-kpi__value{font:var(--ui-kpi);letter-spacing:var(--track-kpi)}
.sf-kpi__delta{font:var(--ui-label);color:var(--text-2)}
.sf-kpi__delta.is-up{color:var(--success-text)}.sf-kpi__delta.is-down{color:var(--error-text)}

/* ---------- Status ---------- */
.sf-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--text-3)}
.sf-dot.is-success{background:var(--success)}.sf-dot.is-warning{background:var(--warning)}
.sf-dot.is-error{background:var(--error)}.sf-dot.is-info{background:var(--info)}.sf-dot.is-caution{background:var(--caution)}
.sf-status-list{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-status-list__row{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-lg);
  background:var(--surface-2);border:1px solid var(--border);color:var(--text);transition:background var(--dur-hover) var(--ease-standard)}
a.sf-status-list__row:hover{text-decoration:none;background:var(--highlight)}
.sf-status-list__text{display:flex;flex-direction:column;flex:1;min-width:0}
.sf-status-list__label{font:var(--ui-label);color:var(--text)}
.sf-status-list__value{font:var(--ui-stat)}
.sf-status-list__value.is-text{font:var(--ui-label);color:var(--text-2)}   /* a word, not a figure ("Done", "Open →": the asset setup steps) */
/* Lanes (x-sf.lanes): a plan against what happened, one row of chips per lane (owner 2026-10-21, voyage page option D) */
.sf-lanes{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:var(--space-3) var(--space-4);align-items:center}
.sf-lanes__label{font:var(--ui-label);color:var(--text-2)}
.sf-lanes__row{display:flex;align-items:center;gap:var(--space-2);margin:0;padding:2px 0;list-style:none;overflow-x:auto;min-width:0}
.sf-lanes__step{display:flex;align-items:center;gap:var(--space-2);flex:none}
.sf-lanes__step+.sf-lanes__step::before{content:'→';color:var(--text-3)}
.sf-lanes__chip{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 var(--space-3);border-radius:var(--radius-pill);border:1px solid var(--border-strong);
  background:var(--surface);font:var(--ui-body);color:var(--text);white-space:nowrap}
.sf-lanes__n{font:var(--ui-meta);font-weight:600;font-variant-numeric:tabular-nums;color:var(--text-3)}
.sf-lanes__step.is-done .sf-lanes__chip{border-color:var(--success)}
.sf-lanes__step.is-planned .sf-lanes__chip{border-style:dashed}
.sf-lanes__step.is-skipped .sf-lanes__chip{border-style:dashed;border-color:var(--error);color:var(--text-3);text-decoration:line-through}
.sf-lanes__step.is-extra .sf-lanes__chip{border-color:var(--warning)}
.sf-lanes__none{color:var(--text-3)}
@media (max-width:639px){.sf-lanes{grid-template-columns:minmax(0,1fr)}}
.sf-status-list>li:has(>.sf-info){display:flex;align-items:center;gap:var(--space-2)}.sf-status-list>li>.sf-status-list__row{flex:1;min-width:0}   /* a row with its ⓘ (F-80) */

/* ---------- Progress ---------- */
.sf-progress{height:6px;border-radius:3px;background:var(--divider);overflow:hidden}
.sf-progress__fill{display:block;height:100%;width:var(--pct,0%);border-radius:3px;background:var(--accent)}
.sf-progress.is-success .sf-progress__fill{background:var(--success)}
.sf-progress.is-warning .sf-progress__fill{background:var(--warning)}
.sf-progress.is-error .sf-progress__fill{background:var(--error)}
/* a limit on the bar (the allowed fill): a thin grey tick a little taller than the bar */
.sf-progress.has-mark{position:relative;overflow:visible}
.sf-progress__mark{position:absolute;top:-3px;bottom:-3px;left:var(--at);width:2px;margin-left:-1px;border-radius:1px;background:var(--text-2)}

/* ---------- Badge ---------- */
.sf-badge{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 8px;border-radius:var(--radius-pill);
  font:var(--ui-meta);font-weight:600;background:var(--surface-2);border:1px solid var(--border);color:var(--text-2);white-space:nowrap}
.sf-badge.is-success{background:var(--success-tint);color:var(--success-text);border-color:transparent}
.sf-badge.is-warning{background:var(--warning-tint);color:var(--warning-text);border-color:transparent}
.sf-badge.is-error{background:var(--error-tint);color:var(--error-text);border-color:transparent}
.sf-badge.is-info{background:var(--info-tint);color:var(--info-text);border-color:transparent}

/* ---------- Avatar ---------- */
.sf-avatar{--size:36px;position:relative;width:var(--size);height:var(--size);border-radius:50%;flex:none;overflow:hidden;
  display:inline-grid;place-items:center;background:var(--highlight);color:var(--accent-text);font:var(--ui-meta);font-weight:700;border:1px solid var(--border)}
.sf-avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* a picture hides the initials (a transparent PNG let them show through); a broken one is removed by sofonn.js, so they return */
.sf-avatar img~.sf-avatar__initials{display:none}
/* face stack (2026-10-19): an optional label, 28 px faces in the one accent tint (opaque: they overlap; owner 2026-10-19: one colour, never one per person), a thin
   glass ring instead of a white sticker, a +N chip with the real rest */
.sf-face-stack{display:inline-flex;align-items:center;gap:var(--space-2)}
.sf-face-stack__label{font:var(--ui-label);color:var(--text-2)}
.sf-face-stack__faces{display:inline-flex;align-items:center}
.sf-face-stack__faces>*+*{margin-left:-4px}   /* more overlap hides the neighbour's initials */
.sf-face-stack .sf-avatar{border:0;font-size:10px;letter-spacing:.02em;box-shadow:0 0 0 2px var(--glass-fill);
  background:color-mix(in srgb,var(--accent) 14%,var(--surface-solid));color:var(--accent-text)}
.sf-face-stack__more{position:relative;height:28px;min-width:28px;padding:0 7px;border-radius:var(--radius-pill);display:inline-grid;place-items:center;
  background:var(--surface-solid);box-shadow:0 0 0 2px var(--glass-fill);font:var(--ui-meta);font-weight:600;color:var(--text-2)}

/* ---------- Empty ---------- */
.sf-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-2);padding:var(--space-10) var(--space-4)}
.sf-empty__icon{width:52px;height:52px;border-radius:15px;display:grid;place-items:center;background:var(--surface-2);border:1px solid var(--border);color:var(--text-2)}

/* ---------- Forms = the design system's Forms card (project a9598b7b components/forms, styles/components.css .sf-input):
   ONE field shape for every input, select, date and the dashboard filters; ONE dropdown (glass, 36 px options, check on the
   selected one); ONE switch (= Navigation > Tabs pill, 40 px, selected = accent). Owner 2026-10-09. ---------- */
.sf-field{display:flex;flex-direction:column;gap:6px;min-width:0}
.sf-field-label{font:var(--ui-label);color:var(--text)}
.sf-field-label b,.sf-frow__t b{color:var(--error-text);font-weight:600}
.sf-field-opt{margin-left:4px;font:var(--ui-meta);color:var(--text-3)}
.sf-field-impact{margin-left:4px;height:18px;padding:0 6px;font:var(--ui-meta);vertical-align:1px}
.sf-field-head{display:flex;flex-wrap:wrap;align-items:center;gap:0 var(--space-1);min-width:0}   /* F-68 <x-slot:info>: the ⓘ inline after the label */
.sf-field-head>.sf-info>summary{margin-block:calc(-1.25 * var(--space-1))}   /* closed: 14 px tall, under the label line (15.6 px), so the row stays one label high */
.sf-field-help{font:var(--ui-meta);color:var(--text-2)}
.sf-field.is-error .sf-field-help{color:var(--error-text)}
.sf-input{display:flex;align-items:center;gap:10px;height:var(--control-md);padding:0 14px;border-radius:var(--radius-md);
  background:var(--field);border:1px solid var(--field-border);color:var(--text);
  transition:border-color var(--dur-hover) var(--ease-standard),box-shadow var(--dur-hover) var(--ease-standard)}
.sf-input input{all:unset;flex:1;align-self:stretch;min-width:0;font:400 14px/1.2 var(--font-sans);color:var(--text)}
.sf-input input::placeholder{color:var(--text-3)}
/* Browser autofill (saved email / password) paints its own grey-blue fill on the inner <input> only, which showed as a box
   inside the field: keep the field's own fill (the fill change is delayed forever) and the theme's text colour. */
.sf-input input:-webkit-autofill,.sf-input input:-webkit-autofill:hover,.sf-input input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--text);caret-color:var(--text);transition:background-color 600000s 0s,color 600000s 0s}
.sf-input .sf-icon{width:18px;height:18px;flex:none;color:var(--text-2)}
/* A field that opens something (dashboard date filter): same box, value + chevron. The chevron is the one every select uses. */
.sf-input--button{cursor:pointer;width:auto;min-width:220px;font:400 14px/1.2 var(--font-sans);color:var(--text);user-select:none}
.sf-input--button>:not(.sf-icon){flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-input--button::after,.sf-chevron::after{content:"";flex:none;width:7px;height:7px;margin:0 3px 3px 6px;border-right:1.5px solid var(--text-2);border-bottom:1.5px solid var(--text-2);transform:rotate(45deg)}
.sf-input--button:focus-visible{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--highlight)}
.sf-input:hover{border-color:var(--border-strong)}
.sf-input:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--highlight)}
.sf-input.is-error,.sf-field.is-error .sf-input{border-color:var(--error-text);box-shadow:0 0 0 3px var(--error-tint)}
.sf-input.is-search{border-radius:var(--radius-pill)}
.sf-input:has(input:disabled){opacity:.4}
/* colour field: a 24 px swatch + its hex in the same 40 px box (never a lone square in an empty wide field) */
.sf-input input[type=color]{flex:none;width:24px;height:24px;align-self:center;border-radius:6px;cursor:pointer;overflow:hidden}
.sf-input input[type=color]::-webkit-color-swatch-wrapper{padding:0}
.sf-input input[type=color]::-webkit-color-swatch{border:1px solid var(--glass-border);border-radius:6px}
.sf-input input[type=color]::-moz-color-swatch{border:1px solid var(--glass-border);border-radius:6px}
.sf-input__hex{flex:1;min-width:0;font:400 14px/1.2 var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text);text-transform:uppercase}
.sf-textarea{position:relative}
.sf-textarea textarea{display:block;width:100%;min-height:96px;padding:10px 14px 24px;border-radius:var(--radius-md);background:var(--field);
  border:1px solid var(--field-border);color:var(--text);font:400 14px/1.5 var(--font-sans);resize:vertical;transition:border-color var(--dur-hover) var(--ease-standard)}
.sf-textarea textarea:hover{border-color:var(--border-strong)}
.sf-textarea textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--highlight)}
.sf-textarea__count{position:absolute;right:12px;bottom:8px}
.sf-select{width:100%;height:var(--control-md);border-radius:var(--radius-md);background:var(--field);border:1px solid var(--field-border);color:var(--text);padding:0 14px;font:400 14px/1.2 var(--font-sans)}
/* glass fields (owner 2026-10-09): every field, select and the dashboard filters = a see-through tint of --field + glass hairline */
.sf-input,.sf-textarea textarea,.sf-select{background:color-mix(in srgb,var(--field) 55%,transparent);border-color:var(--glass-border)}
.sf-check{display:inline-flex;align-items:center;gap:8px;font:var(--ui-body);color:var(--text);cursor:pointer}
.sf-check input{appearance:none;margin:0;width:18px;height:18px;border-radius:5px;border:1.5px solid var(--border-strong);background:var(--field);display:grid;place-content:center;cursor:pointer}
.sf-check input[type=radio]{border-radius:50%}
.sf-check input:checked{background:var(--accent);border-color:var(--accent)}
.sf-check input[type=checkbox]:checked::after{content:"";width:9px;height:5px;border:2px solid var(--text-on-accent);border-top:0;border-right:0;transform:translateY(-1px) rotate(-45deg)}
.sf-check input[type=radio]:checked::after{content:"";width:6px;height:6px;border-radius:50%;background:var(--text-on-accent)}
.sf-check input:focus-visible{box-shadow:var(--focus-ring)}
.sf-toggle-row{display:inline-flex;align-items:center;gap:10px}
.sf-toggle{all:unset;position:relative;width:40px;height:24px;border-radius:12px;background:var(--border-strong);cursor:pointer;flex:none;transition:background var(--dur-fast) var(--ease-standard)}
.sf-toggle::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:var(--surface-solid);box-shadow:var(--shadow-e1);transition:transform var(--dur-fast) var(--ease-standard)}
.sf-toggle[aria-checked="true"]{background:var(--accent)}
.sf-toggle[aria-checked="true"]::after{transform:translateX(16px)}
.sf-toggle:focus-visible{box-shadow:var(--focus-ring)}
.sf-segmented{display:inline-flex;align-items:center;gap:2px;height:var(--control-md);padding:3px;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--field) 55%,transparent);border:1px solid var(--glass-border)}
.sf-segmented__opt input{position:absolute;opacity:0;pointer-events:none}
.sf-segmented__opt span{display:inline-flex;align-items:center;height:32px;padding:0 16px;border-radius:var(--radius-pill);font:600 13px/1 var(--font-sans);color:var(--text-2);white-space:nowrap;cursor:pointer;transition:background var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-segmented__opt span:hover{color:var(--text)}
.sf-segmented__opt input:checked+span{background:var(--accent);color:var(--text-on-accent)}
.sf-segmented__opt input:focus-visible+span{box-shadow:var(--focus-ring)}
/* Phone: a radio switch never runs past the screen; long labels share the width and wrap (Division prices > Transfer day) */
@media (max-width:639px){.sf-segmented:has(.sf-segmented__opt){display:flex;max-width:100%;height:auto;border-radius:var(--radius-lg)}.sf-segmented__opt{flex:1 1 auto;min-width:0;display:flex}.sf-segmented__opt span{flex:1;justify-content:center;height:auto;min-height:32px;padding:6px 10px;white-space:normal;text-align:center;line-height:1.25;border-radius:var(--radius-md)}}

/* ---------- Tabs ---------- */
/* Tabs = the design system's Navigation > Tabs (project a9598b7b styles/components.css): pill bar, selected = accent fill, white text.
   Calm rule (owner 10-08): no glow on the selected tab. variant="underline" = the DS underline tabs, for switches inside a card. */
/* page tab bar = exactly the header/sidebar glass (.sf-glass values); owner 2026-10-09 */
.sf-tabs{display:inline-flex;align-self:flex-start;gap:2px;padding:3px;border-radius:var(--radius-pill);background:var(--glass-fill);border:1px solid var(--glass-border);box-shadow:var(--shadow-e2);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));max-width:100%;overflow-x:auto}
.sf-tab{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 16px;border-radius:var(--radius-pill);font:600 13px/1 var(--font-sans);color:var(--text-2);white-space:nowrap;transition:background var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-tab:hover{text-decoration:none;color:var(--text)}
.sf-tab.is-selected{background:var(--accent);color:var(--text-on-accent)}
.sf-tab:focus-visible{box-shadow:var(--focus-ring)}
.sf-tab__count{font:var(--ui-meta);opacity:.8}
.sf-tabs--underline{gap:24px;padding:0;border:0;border-bottom:1px solid var(--divider);border-radius:0;background:none;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
.sf-tabs--underline .sf-tab{height:40px;padding:0;border-radius:0;background:none}
.sf-tabs--underline .sf-tab.is-selected{background:none;color:var(--text);box-shadow:inset 0 -2px 0 var(--accent)}

/* ---------- Menu (dropdown) ---------- */
.sf-menu{position:relative;display:inline-flex}
/* menus = the header/sidebar glass (the Glass rule: header, sidebar, menus, dropdowns, calendars) */
.sf-menu__panel{position:absolute;top:calc(100% + 6px);right:0;z-index:60;min-width:200px;padding:6px;border-radius:var(--radius-lg);
  background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));border:1px solid var(--glass-border);box-shadow:var(--shadow-e3);display:flex;flex-direction:column;gap:2px}
.sf-menu.is-start .sf-menu__panel{right:auto;left:0}
.sf-menu__item{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:10px;height:36px;padding:0 10px;border-radius:var(--radius-sm);font:var(--ui-body);color:var(--text);cursor:pointer}
.sf-menu__item:hover,.sf-menu__item:focus-visible{background:var(--surface-2);text-decoration:none}
.sf-menu__item .sf-icon{color:var(--text-2)}

/* ---------- Breadcrumb ---------- */
.sf-breadcrumb{display:flex;align-items:center;gap:var(--space-2);font:var(--ui-label);color:var(--text-2);margin-bottom:var(--space-3);min-width:0}
.sf-breadcrumb__list{display:flex;align-items:center;gap:var(--space-1);min-width:0;flex-wrap:wrap;list-style:none;margin:0;padding:0}
.sf-breadcrumb a{color:var(--text-2)}.sf-breadcrumb a:hover{color:var(--text)}
.sf-breadcrumb [aria-current]{color:var(--text)}
.sf-breadcrumb [aria-current]+.sf-info{margin-left:2px}   /* the page ⓘ right after the page's name (sofonn.js infoToTrail) */
.sf-breadcrumb__sep{color:var(--text-3);display:inline-flex}
.sf-breadcrumb__more{position:relative}.sf-breadcrumb__more summary{cursor:pointer;list-style:none}

/* ---------- Pagination ---------- */
.sf-pagination{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.sf-pagination__page{min-width:32px;height:32px;padding:0 8px;border-radius:var(--radius-sm);display:inline-grid;place-items:center;font:var(--ui-button);color:var(--text-2)}
.sf-pagination__page:hover{background:var(--surface-2);text-decoration:none;color:var(--text)}
.sf-pagination__page.is-selected{background:var(--accent);color:var(--text-on-accent)}
.sf-pagination__gap{color:var(--text-3);padding:0 4px}
button.sf-pagination__page{border:0;background:none;cursor:pointer}
button.sf-pagination__page:focus-visible{box-shadow:var(--focus-ring)}
/* the one pager (sf.list._pager + the sofonn.js pager) = the Data table footer: inside a full data table it is the panel's foot;
   anywhere else it keeps the same look with its own hairline (owner 2026-10-15) */
.sf-pager{margin:0}
.sf-pager .sf-pagination .sf-btn-icon{width:32px;height:32px}

.sf-breadcrumb__more .sf-menu__panel{left:0;right:auto}

/* ---------- Data table (reel B: six decisions; owner 2026-10-09: the table is the header/sidebar glass) ---------- */
.sf-dtable{border-radius:var(--radius-xl);overflow:hidden;border:1px solid var(--glass-border);box-shadow:var(--shadow-e2);color:var(--text);min-width:0;background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
.sf-dtable__bar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--divider)}
.sf-dtable__title{display:flex;flex-direction:column;gap:2px;min-width:0;margin-right:var(--space-2)}
.sf-dtable__title>*{margin:0}
.sf-dtable__tools{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);min-width:0}
.sf-dtable__tools .sf-input.is-search{width:240px;max-width:100%}
/* a filter form in a table's toolbar (Daily report History's From / To, 2026-10-13) lays out like the toolbar: one row */
.sf-dtable__tools>form{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.sf-dtable__tools>form .sf-input{width:170px}
/* Phone (owner 2026-10-22, ROB): the toolbar's pickers and search share the width two by two (at least 120 px), a lone one fills its line */
@media (max-width:639px){.sf-dtable__tools>:is(.select2.select2-container,.sf-input),.sf-dtable__tools>form>:is(.select2.select2-container,.sf-input){flex:1 1 120px;width:auto!important;min-width:0;max-width:none}}
.sf-dtable__meta{display:flex;align-items:center;gap:var(--space-3);margin-left:auto}
.sf-dtable__count{font:var(--ui-meta);color:var(--text-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.sf-dtable__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-4);border-top:1px solid var(--divider);font:var(--ui-meta);color:var(--text-3)}
.sf-dtable .sf-table-wrap{max-height:var(--table-max-h,560px)}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-segmented__btn{height:26px;padding:0 12px;font-size:12px}
.sf-table-wrap{width:100%;overflow:auto;max-height:var(--table-max-h,calc(100vh - 180px));-webkit-overflow-scrolling:touch}
@media (max-width:1024px){.sf-table-wrap{max-height:none}}
.sf-table{width:100%;border-collapse:separate;border-spacing:0;font:var(--ui-body);color:var(--text)}
.sf-table th{position:sticky;top:0;z-index:2;background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));text-align:left;font:var(--ui-label);color:var(--text-2);
  padding:0 var(--space-4);height:40px;border-bottom:1px solid var(--divider);white-space:nowrap}
.sf-table td{padding:0 var(--space-4);border-bottom:1px solid var(--divider);background:transparent;max-width:280px;vertical-align:middle}
.sf-table.is-40 td{height:40px}.sf-table.is-48 td{height:48px}.sf-table.is-56 td{height:56px}
/* Appearance > Table rows (one preference for every table; Auto = no attribute = each table's own height) */
html[data-table-density="40"] .sf-table td{height:40px}html[data-table-density="48"] .sf-table td{height:48px}html[data-table-density="56"] .sf-table td{height:56px}
.sf-table tbody tr:hover{--sf-row-tint:color-mix(in srgb,var(--accent) 7%,transparent)}.sf-table tbody tr:hover td{background:var(--sf-row-tint)}
.sf-table tbody tr:last-child td{border-bottom:0}
.sf-table .is-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;max-width:none}
.sf-table.has-sticky-col th:first-child,.sf-table.has-sticky-col td:first-child{position:sticky;left:0;z-index:1}
/* pinned identity cell: opaque only while the table is scrolled sideways, so the columns sliding under it never show
   through; at rest it is the row itself, no other colour (owner 2026-10-19: "the first column has a different colour").
   Glass over the solid surface, no backdrop blur (a blurred layer drew its text thinner than the row's, dark 10-11), tinted
   like its row (--sf-row-tint: hover / focus / ticked); tbody tr = specificity above the row-state td rules */
.sf-table-wrap.is-scrolled-x .sf-table.has-sticky-col tbody tr td:first-child,.sf-table-wrap.is-scrolled-x .sf-table.has-sticky-2 tbody tr td:nth-child(2){background:linear-gradient(var(--sf-row-tint,transparent),var(--sf-row-tint,transparent)),linear-gradient(var(--glass-fill),var(--glass-fill)),var(--surface-solid)}
/* 2nd pinned identity column: its left offset = the 1st column's width (sofonn.js sets --sf-pin-1) */
.sf-table.has-sticky-2 th:nth-child(2),.sf-table.has-sticky-2 td:nth-child(2){position:sticky;left:var(--sf-pin-1,0px);z-index:1}
.sf-table.has-sticky-2 th:nth-child(2){z-index:3}
/* edge under the last pinned column, only while the table is scrolled sideways */
.sf-table-wrap.is-scrolled-x .sf-table.has-sticky-col:not(.has-sticky-2) :is(th,td):first-child,
.sf-table-wrap.is-scrolled-x .sf-table.has-sticky-2 :is(th,td):nth-child(2){box-shadow:8px 0 12px -8px color-mix(in srgb,var(--text) 30%,transparent)}
/* keyboard: the focused row is marked, its actions show (decision 06) */
.sf-table tbody tr:focus-within{--sf-row-tint:var(--highlight)}.sf-table tbody tr:focus-within td{background:var(--highlight)}
.sf-table tbody tr:focus-within td:first-child{box-shadow:inset 2px 0 0 var(--accent)}
/* stripes only earn very wide tables (12+ columns): opt-in */
.sf-table.is-striped tbody tr:nth-child(even) td{background:color-mix(in srgb,var(--text) 3%,transparent)}
/* cells */
.sf-table td.is-id{font-variant-numeric:tabular-nums slashed-zero;letter-spacing:.02em;color:var(--text-2);font-weight:500;white-space:nowrap}
.sf-cell-person{display:flex;align-items:center;gap:var(--space-2);min-width:0}
.sf-cell-two{display:flex;flex-direction:column;min-width:0;line-height:1.25}   /* a cell with a second grey line (charterer + scope location) */
.sf-vtime{display:inline-flex;flex-direction:column;line-height:1.25;font-variant-numeric:tabular-nums}.sf-vtime--end{align-items:flex-end;text-align:right}   /* <x-sf.vessel-time>: vessel time, the UTC under it (owner 2026-10-20) */
.sf-vtime__utc{font:var(--ui-meta);color:var(--text-2);white-space:nowrap}
.sf-cell-person .sf-avatar{--size:24px;font-size:10px}
.sf-cell-empty{color:var(--text-3)}
.sf-table td .sf-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* loading: skeleton rows while the table has data-sf-loading */
.sf-table[data-sf-loading]>tbody:not(.sf-table__skel){display:none}
.sf-table:not([data-sf-loading])>tbody.sf-table__skel{display:none}
.sf-table__skel td{height:inherit}
.sf-table.has-sticky-col th:first-child{z-index:3}
.sf-table td .sf-truncate{display:block}
@media (pointer:coarse){.sf-table td a.sf-truncate{padding-block:4px}}   /* touch: a name link in a cell is at least 24 px tall */
.sf-th-sort{display:inline-flex;align-items:center;gap:4px;color:inherit}
.sf-th-sort:hover{color:var(--text);text-decoration:none}
.sf-sort-arrow{transition:transform var(--dur-fast) var(--ease-standard)}
.sf-sort-arrow.is-desc{transform:rotate(180deg)}
.sf-row-actions{display:flex;justify-content:flex-end;gap:2px;opacity:0;transition:opacity var(--dur-hover) var(--ease-standard)}
.sf-table tr:hover .sf-row-actions,.sf-table tr:focus-within .sf-row-actions{opacity:1}
.sf-row-kebab{display:none}
.sf-table td:has(> .sf-row-actions),.sf-table td:has(> .sf-row-kebab),.sf-table td:has(> .sf-row-menu){text-align:right}
/* A row's own menu (.sf-row-menu, e.g. View + status changes) follows the row-action rule: hidden at rest, shown on row hover/focus and while open. */
.sf-row-menu{opacity:0;pointer-events:none;transition:opacity var(--dur-hover) var(--ease-standard)}
.sf-table tr:hover .sf-row-menu,.sf-table tr:focus-within .sf-row-menu,.sf-row-menu:has(> [aria-expanded="true"]){opacity:1;pointer-events:auto}
/* Phone (<640): desktop cell padding (16 px a side) let the pinned identity cell + the next columns fill the screen, so the person and the
   row actions started off-screen with nothing hinting at them. Tighter cells, a capped identity cell (it truncates with its tooltip), and
   the actions cell pinned right with an edge, like the identity column on the left. */
@media (max-width:639px){.sf-table :is(th,td){padding:0 var(--space-2)}
  .sf-table.has-sticky-col td:first-child{max-width:33vw}
  /* checkbox + name lists (Locations, Certificates): pinned checkbox + 280 px name + ⋯ filled the screen. The checkbox scrolls, the name is pinned at a third */
  .sf-table.has-sticky-2 :is(th,td):first-child{position:static}
  .sf-table.has-sticky-2 :is(th,td):nth-child(2){left:0}
  .sf-table.has-sticky-2 td:nth-child(2){max-width:33vw}
  .sf-table td:last-child:has(> .sf-row-actions){position:sticky;right:0;z-index:1;background:linear-gradient(var(--sf-row-tint,transparent),var(--sf-row-tint,transparent)),linear-gradient(var(--glass-fill),var(--glass-fill)),var(--surface-solid);box-shadow:-8px 0 12px -8px color-mix(in srgb,var(--text) 30%,transparent)}
  .sf-table:has(td:last-child > .sf-row-actions) th:last-child{position:sticky;right:0;z-index:3}}
/* A narrow desktop window: the actions show on hover only, so the pinned cell stays clear at rest (it read as an empty box). */
@media (max-width:639px) and (hover:hover){.sf-table tr:not(:hover):not(:focus-within) td:last-child:has(> .sf-row-actions){background:none;box-shadow:none}}
/* Stacked rows (x-sf.table :stack, 2026-11-05): on a phone a row is a two-column block, not a table that scrolls sideways. Cells in their
   order on the left, cells with data-sf-end on the right (status, switch, actions), empty cells left out; nothing pinned. */
@media (max-width:639px){
  .sf-table.is-stack thead{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  .sf-table.is-stack,.sf-table.is-stack>tbody{display:block}
  .sf-table.is-stack>tbody>tr{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-auto-flow:row dense;align-items:center;gap:var(--space-1) var(--space-3);padding:var(--space-3);border-bottom:1px solid var(--divider)}
  .sf-table.is-stack>tbody>tr:last-child{border-bottom:0}
  .sf-table.is-stack>tbody>tr:hover{background:var(--sf-row-tint)}
  .sf-table.is-stack>tbody>tr>td{grid-column:1;height:auto!important;padding:0;border:0;max-width:none;background:none}
  .sf-table.is-stack>tbody>tr>td[data-sf-end]{grid-column:2;justify-self:end;text-align:right}
  .sf-table.is-stack>tbody>tr>td[colspan]{grid-column:1/-1}
  .sf-table.is-stack>tbody>tr>td:is(:empty,:has(>.sf-cell-empty:only-child)){display:none}
  .sf-table.is-stack.has-sticky-col td:first-child,.sf-table.is-stack td:last-child:has(> .sf-row-actions){position:static;max-width:none;background:none;box-shadow:none}
}
/* A pinned cell is its own layer, so the next row's pinned ⋯ cell painted over an open menu (Consumption reference, phone). Lift the cell while its menu is open. */
.sf-table td:has(.sf-menu__panel:not([hidden])){z-index:4}
@media (hover:none){
  .sf-row-actions[data-sf-kebab]{display:none}
  .sf-row-kebab{display:inline-flex}
  .sf-row-menu{opacity:1;pointer-events:auto}
}

/* ---------- Alert / toast / tooltip ---------- */
.sf-alert{display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-4);border-radius:var(--radius-lg);border:1px solid var(--border);background:var(--surface-2)}
.sf-alert__title{font:var(--ui-card-title);color:var(--text)}
.sf-alert__text{font:var(--ui-body);color:var(--text-2)}
.sf-alert.is-info{background:var(--info-tint);border-color:transparent}.sf-alert.is-info>.sf-icon{color:var(--info-text)}
.sf-alert.is-success{background:var(--success-tint);border-color:transparent}.sf-alert.is-success>.sf-icon{color:var(--success-text)}
.sf-alert.is-warning{background:var(--warning-tint);border-color:transparent}.sf-alert.is-warning>.sf-icon{color:var(--warning-text)}
.sf-alert.is-error{background:var(--error-tint);border-color:transparent}.sf-alert.is-error>.sf-icon{color:var(--error-text)}
.sf-toasts{position:fixed;right:var(--space-4);bottom:var(--space-4);z-index:200;display:flex;flex-direction:column;gap:var(--space-2);max-width:calc(100vw - 2 * var(--space-4))}
.sf-toast{width:360px;max-width:100%;padding:var(--space-3) var(--space-4);border-radius:var(--radius-lg);background:var(--surface-elevated);border:1px solid var(--border);box-shadow:var(--shadow-e3);font:var(--ui-body);color:var(--text)}
.sf-toast.is-error{border-color:var(--error-text)}.sf-toast.is-success{border-color:var(--success-text)}.sf-toast.is-warning{border-color:var(--warning-text)}
/* tooltip = the header/sidebar glass (owner 2026-10-09) */
.sf-tip{position:fixed;left:var(--x);top:var(--y);transform:translate(-50%,-100%);z-index:300;padding:6px 10px;border-radius:var(--radius-sm);border:1px solid var(--glass-border);box-shadow:var(--shadow-e2);color:var(--text);font:var(--ui-meta);pointer-events:none;white-space:nowrap;max-width:min(420px,90vw);background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}

/* ---------- Modal ---------- */
.sf-modal{width:480px;max-width:calc(100vw - 32px);padding:0;border:1px solid var(--glass-border);border-radius:var(--radius-xl);background:transparent;isolation:isolate;color:var(--text);box-shadow:var(--shadow-e2)}
.sf-modal::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:var(--glass-fill);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
@media (prefers-reduced-transparency:reduce){.sf-modal::before{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--surface-elevated)}}
.sf-modal.is-lg{width:760px}
.sf-modal::backdrop{background:var(--scrim);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.sf-modal__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-5) var(--space-6) 0}
.sf-modal__title{font:700 18px/1.3 var(--font-sans);color:var(--text)}
.sf-modal__body{padding:var(--space-4) var(--space-6)}
.sf-modal__foot{display:flex;justify-content:flex-end;gap:var(--space-2);padding:0 var(--space-6) var(--space-5)}

/* ---------- Loader / skeleton ---------- */
.sf-spinner{--size:18px;display:inline-block;width:var(--size);height:var(--size);border-radius:50%;border:2px solid currentColor;border-right-color:transparent;animation:sf-spin .8s linear infinite;color:var(--text-2)}
@keyframes sf-spin{to{transform:rotate(360deg)}}
.sf-skeleton{display:block;width:var(--w);height:var(--h);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--text) 9%,transparent)}   /* visible on glass in light and dark */
.sf-toasts.is-in-dialog{position:fixed}

/* ---------- Shell ---------- */
.sf-skip{position:absolute;left:-9999px}.sf-skip:focus{left:var(--space-4);top:var(--space-4);z-index:500;padding:var(--space-2) var(--space-3);background:var(--surface-elevated);border-radius:var(--radius-sm)}
.sf-shell{display:grid;grid-template-columns:240px minmax(0,1fr);grid-template-rows:auto 1fr;gap:var(--space-4);padding:var(--space-4);min-height:100vh}
.sf-shell>.sf-header{grid-column:1/-1}
.sf-main{min-width:0;padding:var(--space-2) var(--space-4) var(--space-12)}
.sf-shell:not(:has(.sf-sidebar)) .sf-main{grid-column:1/-1}
.sf-logo-dark{display:none}
[data-bs-theme="dark"] .sf-logo-light{display:none}[data-bs-theme="dark"] .sf-logo-dark{display:block}

/* ---------- Header (Figma 7.3: 64 px glass pill) ---------- */
.sf-header{position:sticky;top:var(--space-4);z-index:50;display:flex;align-items:center;gap:var(--space-4);height:64px;padding:0 var(--space-3) 0 var(--space-5);border-radius:var(--radius-pill);box-shadow:var(--shadow-e2);transition:height var(--dur-base) var(--ease-standard)}
.sf-header__menu{display:none}
.sf-header__logo{display:flex;align-items:center}
.sf-header__end{margin-left:auto;display:flex;align-items:center;gap:var(--space-2)}
.sf-header__bell{position:relative}
/* Notifications dropdown (<x-sf.notifications-menu>): header-glass panel, 360 px, unread list, mark read, view all */
.sf-notif__panel{width:360px;max-width:calc(100vw - 24px);padding:0;gap:0;overflow:hidden}
.sf-notif__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-3) var(--space-3) var(--space-3) var(--space-4);border-bottom:1px solid var(--divider)}
.sf-notif__head .sf-card-title{margin:0}
.sf-notif__tools{display:flex;align-items:center;gap:var(--space-1)}
.sf-notif__soundbox{display:flex;align-items:center}
.sf-notif__vol{width:0;margin:0;opacity:0;accent-color:var(--accent);transition:width var(--m-expand) var(--m-expand-ease),opacity var(--m-expand) var(--m-expand-ease)}
.sf-notif__soundbox:hover .sf-notif__vol,.sf-notif__soundbox:focus-within .sf-notif__vol{width:88px;opacity:1}
@media (hover:none){.sf-notif__vol{width:72px;opacity:1}}
.sf-notif__sound[aria-pressed="true"] [data-off],.sf-notif__sound:not([aria-pressed="true"]) [data-on]{display:none}
.sf-notif__list{display:flex;flex-direction:column;max-height:360px;overflow-y:auto;overscroll-behavior:contain;padding:4px}
.sf-notif__item{position:relative;display:flex;align-items:flex-start;gap:var(--space-1);border-radius:var(--radius-md)}
.sf-notif__item:hover,.sf-notif__item:focus-within{background:var(--surface-2)}
.sf-notif__link{flex:1;min-width:0;display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--space-3);color:var(--text);text-decoration:none}
.sf-notif__link:hover{text-decoration:none}
.sf-notif__ic{flex:none;width:32px;height:32px;border-radius:50%;display:grid;place-items:center;background:var(--highlight);color:var(--accent-text)}
/* quiet bell (owner 2026-11-06): an alert's icon wears the warning tint; Today / Earlier headings, one with nothing under it is hidden */
.sf-notif__ic.is-alert{background:var(--warning-tint);color:var(--warning-text)}
.sf-notif__group{margin:0;padding:var(--space-2) var(--space-3) var(--space-1);font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-2)}
.sf-notif__group:has(+ .sf-notif__group),.sf-notif__group:has(+ .sf-notif__empty){display:none}
.sf-notif__body{display:flex;flex-direction:column;gap:2px;min-width:0}
.sf-notif__msg{font:var(--ui-body);color:var(--text);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sf-notif__time{font:var(--ui-meta);color:var(--text-3)}
.sf-notif__read{flex:none;margin:var(--space-2) var(--space-2) 0 0;opacity:0;transition:opacity var(--dur-hover) var(--ease-standard)}
.sf-notif__item:hover .sf-notif__read,.sf-notif__item:focus-within .sf-notif__read{opacity:1}
@media (hover:none){.sf-notif__read{opacity:1}}
.sf-notif__empty{margin:0;padding:var(--space-8) var(--space-4);text-align:center;font:var(--ui-body);color:var(--text-2)}
.sf-notif__foot{display:block;padding:var(--space-3);text-align:center;border-top:1px solid var(--divider);font:var(--ui-button);color:var(--accent-text)}
.sf-notif__foot:hover{background:var(--surface-2);text-decoration:none}
.sf-header__count{position:absolute;top:4px;right:2px;min-width:16px;height:16px;padding:0 4px;border-radius:var(--radius-pill);background:var(--error);color:var(--text-on-accent);font:700 11px/16px var(--font-sans);text-align:center}
.sf-account__trigger{all:unset;display:flex;align-items:center;gap:var(--space-2);padding:4px 10px 4px 4px;border-radius:var(--radius-pill);cursor:pointer;font:var(--ui-label);color:var(--text)}
.sf-account__trigger:hover{background:var(--surface-2)}
.sf-account__trigger:focus-visible{box-shadow:var(--focus-ring)}
.sf-account__panel{width:300px}
.sf-account__who{padding:var(--space-2) 10px var(--space-3);border-bottom:1px solid var(--divider);margin-bottom:4px}
.sf-account__rec{width:6px;height:6px;border-radius:50%;background:var(--error)}
.sf-account__panel form{display:contents}
/* Guides side menu (one row in the account menu, its items in a panel beside it — like the old account menu) */
.sf-submenu{position:relative}
.sf-submenu__trigger{width:100%}
.sf-submenu__label{flex:1;min-width:0}
.sf-submenu__chev{color:var(--text-3)}
.sf-submenu__trigger[aria-expanded="true"]{background:var(--surface-2)}
.sf-submenu__panel{top:-6px;right:calc(100% + 10px);min-width:225px}
/* Appearance: Background dots (same data-bg-set hook as the old menu; preview on hover, keep on click) */
.sf-bg-dots{display:flex;flex-wrap:wrap;gap:8px}
/* Appearance switches fill the menu width, equal segments (Table rows has four options) */
.sf-appearance .sf-segmented{display:flex;width:100%}
.sf-appearance .sf-segmented__btn{flex:1 1 0;justify-content:center;min-width:0;padding:0 6px;font-size:12px}
.sf-bg-dot{all:unset;box-sizing:border-box;width:24px;height:24px;border-radius:50%;cursor:pointer;background:var(--thumb-light) center/cover no-repeat;border:2px solid var(--border);transition:border-color var(--dur-hover) var(--ease-standard)}
[data-bs-theme="dark"] .sf-bg-dot{background-image:var(--thumb-dark)}
.sf-bg-dot:hover{border-color:var(--border-strong)}
.sf-bg-dot.sel{border-color:var(--accent)}
.sf-bg-dot:focus-visible{box-shadow:var(--focus-ring)}
/* Appearance side panel (option A): labelled blocks, each control full width, one rhythm */
.sf-appearance.sf-submenu__panel{width:300px;padding:var(--space-4);gap:var(--space-4)}
.sf-appearance__block{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-appearance__block>.sf-label{margin:0;font:var(--ui-label);color:var(--text-2)}
.sf-segmented__btn{all:unset;box-sizing:border-box;display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 16px;border-radius:var(--radius-pill);font:600 13px/1 var(--font-sans);color:var(--text-2);cursor:pointer}
.sf-segmented__btn:focus-visible{box-shadow:var(--focus-ring)}
/* the selected option: .sel, or the a11y state a page already sets (aria-pressed on a button, aria-current on a link) */
.sf-segmented__btn:is(.sel,[aria-pressed="true"],[aria-current="page"]){background:var(--accent);color:var(--text-on-accent)}
.sf-segmented__btn:not(.sel,[aria-pressed="true"],[aria-current="page"]):hover{color:var(--text)}
.sf-header.is-compact{height:52px}
@media (max-width:1279px){
  .sf-shell{grid-template-columns:minmax(0,1fr)}
  .sf-header__menu{display:inline-flex}
}
@media (max-width:639px){
  .sf-shell{padding:var(--space-2);gap:var(--space-2)}
  .sf-main{padding:var(--space-2) var(--space-1) var(--space-10)}
  .sf-hide-sm{display:none}
  .sf-header__bell{display:none}   /* spec §5: logo, menu toggle and account only; the Fleet selector came back (owner 2026-10-22) */
  .sf-submenu__panel{position:static;margin:2px 0 4px;box-shadow:none;min-width:0}
  .sf-appearance.sf-submenu__panel{width:auto;padding:var(--space-3);gap:var(--space-3)}   /* opened under its row: tighter, so Sign out stays on a 667 px screen */
}

/* ---------- Sidebar (Figma 7.3): 240 px glass panel, fold-open groups, collapses to a 64 px rail (.is-rail, >= 1280 px) ---------- */
/* Full height: from just under the sticky header (16 px gap + 64 px header + 16 px gap) to 16 px above the window bottom; stays put while
   the page scrolls; the item list scrolls inside, the user chip + Collapse stay pinned at the bottom. */
.sf-sidebar{--sf-side-top:calc(var(--space-4) + 64px + var(--space-4));position:sticky;top:var(--sf-side-top);align-self:start;display:flex;flex-direction:column;width:240px;height:calc(100vh - var(--sf-side-top) - var(--space-4));border-radius:var(--radius-xl);box-shadow:var(--shadow-e2);z-index:40;overflow:hidden}
.sf-sidebar__scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:var(--space-3);display:flex;flex-direction:column;gap:2px}
.sf-sidebar__foot{padding:var(--space-3);border-top:1px solid var(--divider);display:flex;flex-direction:column;gap:var(--space-2)}
/* the user menu (the old sidebar's): name block = the trigger, panel opens upward over the item list (inside the sidebar, so not clipped) */
.sf-sidebar__me{display:flex;align-items:center;gap:var(--space-1);min-width:0}
.sf-sidebar__menu{flex:1;min-width:0;position:static}
.sf-sidebar__user{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:var(--space-2);width:100%;min-width:0;padding:4px;border-radius:var(--radius-md);cursor:pointer;transition:background var(--dur-hover) var(--ease-standard)}
.sf-sidebar__user:hover,.sf-sidebar__user[aria-expanded="true"]{background:var(--surface-2)}
.sf-sidebar__user:focus-visible{box-shadow:var(--focus-ring)}
.sf-sidebar__foot{position:relative}
.sf-sidebar__panel{top:auto;bottom:calc(100% + 4px);left:var(--space-3);right:var(--space-3);min-width:0}
.sf-sidebar__roles{display:flex;flex-wrap:wrap;gap:4px;margin:var(--space-2) 0 0}
.sf-sidebar__out{flex:none}
.sf-sidebar__who{display:flex;flex-direction:column;min-width:0}
.sf-sidebar__name{font:var(--ui-label);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-sidebar__who .sf-meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-nav-item{all:unset;box-sizing:border-box;position:relative;display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:var(--control-md);padding:0 var(--space-3);border-radius:var(--radius-md);font:var(--ui-label);color:var(--text-2);cursor:pointer;transition:background var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-nav-item .sf-icon{flex:0 0 auto;color:var(--text-3);transition:color var(--dur-hover) var(--ease-standard)}
.sf-nav-item:hover{background:var(--surface-2);color:var(--text)}
.sf-nav-item:focus-visible{box-shadow:var(--focus-ring)}
.sf-nav-item__label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-nav-item.is-active{background:var(--highlight);color:var(--text)}
.sf-nav-item.is-active .sf-icon{color:var(--accent-text)}
.sf-nav-item.is-current{color:var(--text)}
.sf-nav-item.is-current>.sf-icon:not(.sf-nav-item__chev){color:var(--accent-text)}
.sf-nav-item__chev{transition:transform var(--dur-hover) var(--ease-standard)}
.sf-nav-item[aria-expanded="true"] .sf-nav-item__chev{transform:rotate(180deg)}
.sf-nav-item__count{min-width:18px;height:18px;padding:0 5px;border-radius:var(--radius-pill);background:var(--error);color:var(--text-on-accent);font:700 11px/18px var(--font-sans);text-align:center;font-variant-numeric:tabular-nums}
.sf-nav-group{margin:2px 0 4px 20px;padding-left:var(--space-2);border-left:1px solid var(--divider);display:flex;flex-direction:column;gap:2px}
.sf-nav-group .sf-nav-item{min-height:var(--control-sm)}
.sf-nav-group__title{display:none}
/* a sub-group (3rd level) indents less, so its page names keep their room */
.sf-nav-group .sf-nav-group{margin-left:var(--space-3)}
.sf-sidebar-scrim{position:fixed;inset:0;z-index:35;background:var(--scrim)}
/* 64 px rail (desktop only; the drawer always shows full labels). Group panels open as flyouts beside the rail: position:absolute against
   the nav, placed by sofonn.js in nav coordinates (a fixed flyout would also resolve against the nav, since its backdrop-filter is a containing block). */
@media (min-width:1280px){
  .sf-shell:has(.sf-sidebar.is-rail){grid-template-columns:64px minmax(0,1fr)}
  .sf-sidebar.is-rail{width:64px;overflow:visible}
  .sf-sidebar{transition:width var(--dur-base) var(--ease-standard)}
  .sf-sidebar.is-rail .sf-sidebar__scroll{overflow:visible;padding:var(--space-2)}
  .sf-sidebar.is-rail .sf-nav-item{justify-content:center;padding:0}
  .sf-sidebar.is-rail .sf-nav-item__chev{display:none}
  .sf-sidebar.is-rail .sf-nav-item>.sf-nav-item__label,.sf-sidebar.is-rail .sf-sidebar__who{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .sf-sidebar.is-rail .sf-nav-item__count{position:absolute;top:4px;right:6px;min-width:8px;width:8px;height:8px;padding:0;font-size:0}
  .sf-sidebar.is-rail .sf-sidebar__user{justify-content:center}
  .sf-sidebar.is-rail .sf-sidebar__out{display:none}
  .sf-sidebar.is-rail .sf-sidebar__panel{left:calc(100% + var(--space-2));right:auto;bottom:var(--space-2);width:260px}
  .sf-sidebar:not(.is-rail) .sf-sidebar__rail .sf-icon{transform:rotate(180deg)}
  .sf-sidebar.is-rail .sf-nav-group{position:absolute;z-index:60;min-width:208px;margin:0;padding:var(--space-2);border:1px solid var(--glass-border);border-radius:var(--radius-lg);background:var(--surface-elevated);box-shadow:var(--shadow-e3)}
  .sf-sidebar.is-rail .sf-nav-group .sf-nav-item{justify-content:flex-start;padding:0 var(--space-3)}
  .sf-sidebar.is-rail .sf-nav-group .sf-nav-item>.sf-nav-item__label{position:static;width:auto;height:auto;clip:auto}
  .sf-sidebar.is-rail .sf-nav-group__title{display:block;padding:var(--space-1) var(--space-3) var(--space-2);font:var(--ui-kicker);color:var(--text-3)}
  /* a sub-group (3 levels, owner 2026-11-02) opens in place inside its parent's flyout: the accordion look, not a second flyout */
  .sf-sidebar.is-rail .sf-nav-group .sf-nav-group{position:static;min-width:0;margin:2px 0 4px var(--space-3);padding:0 0 0 var(--space-2);border:0;border-left:1px solid var(--divider);border-radius:0;background:none;box-shadow:none}
  .sf-sidebar.is-rail .sf-nav-group .sf-nav-group__title{display:none}
  .sf-sidebar.is-rail .sf-nav-group .sf-nav-item__chev{display:block}
}
/* Below 1280: the sidebar is a drawer opened by the header button. It starts below the sticky header (z 50) so the header toggle
   stays reachable to close it; align-self:stretch because a fixed grid child would otherwise shrink to its content. */
@media (max-width:1279px){
  .sf-sidebar{position:fixed;top:calc(var(--space-4) + 64px + var(--space-2));left:var(--space-2);bottom:var(--space-2);align-self:stretch;height:auto;max-height:none;width:min(280px,calc(100vw - 32px));z-index:40;transform:translateX(calc(-100% - var(--space-4)));transition:transform var(--dur-base) var(--ease-standard);visibility:hidden}
  .sf-sidebar.is-open{transform:none;visibility:visible}
  .sf-sidebar__rail{display:none}
}

/* ---------- Fleet selector (header; markup + hooks from components/sf/fleet-search, behaviour fleet-search.js) ---------- */
.sf-header .fs-root{position:relative}
/* The kit's Select (components/forms/Select.jsx): 32 px glass pill, 180 px, icon + 13/700 value + small chevron. */
.sf-header .fs-trigger{--h:32px;--px:12px;width:180px;padding-left:14px;justify-content:space-between;border-radius:var(--radius-pill);background:var(--glass-fill);border-color:var(--glass-border);font:700 13px/1 var(--font-sans);color:var(--text)}
.sf-header .fs-trigger:hover{background:var(--surface-2)}
.sf-header .fs-trigger .fs-ico-sm{transition:transform var(--dur-base) var(--ease-standard)}
.sf-header .fs-trigger[aria-expanded="true"] .fs-ico-sm{transform:rotate(180deg)}
@media (max-width:639px){.sf-header .fs-trigger{width:32px;padding:0;justify-content:center}.sf-header .fs-trigger .fs-ico-sm{display:none}}   /* phone: the ship icon alone, like the compact header (after the 180 px rule, owner 2026-10-22) */
.sf-header .fs-ico{width:16px;height:16px;flex:0 0 16px}
.sf-header .fs-ico-sm{width:12px;height:12px;flex-basis:12px}
.sf-header .fs-panel{display:none;width:380px;max-width:calc(100vw - 24px);padding:var(--space-2);flex-direction:column;font:var(--ui-body);color:var(--text)}
.sf-header .fs-panel.show{display:flex}
/* Fleet search (owner 2026-10-10: cramped, double focus ring): the one field shape (40 px, radius 10, 55 % field tint, glass edge),
   one focus ring on the box; two-line rows 48 px with a 2 px gap; the second line 11 px grey on one line. */
.sf-header .fs-search{display:flex;align-items:center;gap:var(--space-2);height:var(--control-md);padding:0 12px;margin:0 0 var(--space-2);border-radius:var(--radius-md);background:color-mix(in srgb,var(--field) 55%,transparent);border:1px solid var(--glass-border)}
.sf-header .fs-search:focus-within{box-shadow:var(--focus-ring)}
.sf-header .fs-search-ico{color:var(--text-3)}
.sf-header .fs-input{flex:1;min-width:0;height:100%;border:0;outline:0;background:transparent;color:var(--text);font:var(--ui-body);padding:0}
.sf-header .fs-input:focus,.sf-header .fs-input:focus-visible{outline:0;box-shadow:none}   /* the ring is the box's (:focus-within) */
.sf-header .fs-input::placeholder{color:var(--text-3)}
.sf-header .fs-clear{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:0;border-radius:var(--radius-xs);background:transparent;color:var(--text-2);cursor:pointer}
.sf-header .fs-clear:hover{background:var(--surface-2)}
.sf-header .fs-status{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.sf-header .fs-scroll{max-height:min(60vh,520px);overflow-y:auto;overscroll-behavior:contain;padding:var(--space-2) 0 0;margin-top:var(--space-1);border-top:1px solid var(--divider)}
.sf-header .fs-suggest,.sf-header .fs-recent{padding:0 0 var(--space-1)}
.sf-header .fs-eyebrow{display:flex;align-items:center;justify-content:space-between;padding:var(--space-1) 10px var(--space-1);font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-2)}
.sf-header .fs-textbtn{border:0;background:transparent;padding:2px 6px;border-radius:var(--radius-xs);cursor:pointer;color:var(--text-2);font:var(--ui-meta);letter-spacing:0;text-transform:none}
.sf-header .fs-textbtn:hover{color:var(--text);background:var(--surface-2)}
.sf-header .fs-row{display:flex;align-items:center;gap:10px;min-height:36px;padding:0 10px 0 calc(10px + var(--fs-depth,0) * 16px);border-radius:var(--radius-sm);color:var(--text);text-decoration:none;cursor:pointer;user-select:none}
.sf-header .fs-row:hover,.sf-header .fs-row.is-focus{background:var(--surface-2);text-decoration:none}
.sf-header .fs-row.is-active{background:var(--highlight);color:var(--accent-text)}
.sf-header .fs-row.is-static{cursor:default}.sf-header .fs-row.is-static:hover{background:transparent}
.sf-header .fs-row--division{padding-right:6px;font-weight:600}
.sf-header .fs-rowlink{display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:0;min-height:36px;color:inherit;text-decoration:none}
.sf-header .fs-text{display:flex;flex-direction:column;justify-content:center;gap:2px;flex:1;min-width:0;line-height:1.3}
.sf-header .fs-row:has(.fs-text>:nth-child(2)){min-height:48px;padding-top:4px;padding-bottom:4px}   /* two lines: room to breathe */
.sf-header .fs-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}
.sf-header .fs-text>.fs-name{flex:none}   /* in a two-line row the name keeps its height (no stretched gap) */
.sf-header .fs-name--muted{color:var(--text-2);font-weight:600}
.sf-header :is(.fs-meta,.fs-path){font:var(--ui-meta);line-height:1.3;color:var(--text-2);font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-header .fs-count{margin-left:auto;flex:none;min-width:22px;height:20px;padding:0 7px;border-radius:var(--radius-pill);display:inline-flex;align-items:center;justify-content:center;border:0;background:color-mix(in srgb,var(--text) 7%,transparent);color:var(--text-2);font:var(--ui-meta);font-variant-numeric:tabular-nums}
.sf-header .fs-ship{color:var(--text-3)}
.sf-header .fs-row.is-active .fs-ship,.sf-header .fs-row.is-active :is(.fs-meta,.fs-path),.sf-header .fs-row.is-active .fs-count{color:inherit}
.sf-header .fs-dot{flex:0 0 6px;width:6px;height:6px;border-radius:50%;background:var(--error)}
.sf-header mark.fs-mark{background:var(--highlight);color:inherit;border-radius:3px;padding:0 1px}
.sf-header .fs-fold,.sf-header .fs-fold-spacer{flex:0 0 24px;width:24px;height:24px}
.sf-header .fs-fold{display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:var(--radius-xs);background:transparent;color:var(--text-3);cursor:pointer}
.sf-header .fs-fold:hover{background:var(--surface-2);color:var(--text)}
.sf-header .fs-fold .fs-ico-sm{transform:rotate(90deg);transition:transform var(--dur-base) var(--ease-standard)}
.sf-header .fs-fold[aria-expanded="false"] .fs-ico-sm{transform:rotate(0)}
.sf-header .fs-group[data-collapsed]>.fs-vessels{display:none}
.sf-header .fs-panel.is-searching .fs-group[data-collapsed]>.fs-vessels{display:block}
.sf-header .fs-subdivisions{position:relative}
.sf-header .fs-subdivisions::before{content:"";position:absolute;top:4px;bottom:4px;left:calc(22px + var(--fs-depth,0) * 16px);width:1px;background:var(--divider)}
.sf-header .fs-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;padding:28px 16px 24px;color:var(--text-3)}
.sf-header .fs-empty-title{color:var(--text-2);font-weight:600}
.sf-header .fs-row:focus-visible,.sf-header .fs-fold:focus-visible,.sf-header .fs-clear:focus-visible,.sf-header .fs-textbtn:focus-visible{box-shadow:var(--focus-ring)}
@media (hover:none){.sf-header .fs-row{min-height:44px}}
/* the fleet filter (origin/main 2026-10-10, the Fleet menu's "Show only this on every page"): a 26 px icon button at the row's right end, hidden at rest, shown on the row's hover / focus (always on touch); on = accent tint. A click filters, it never opens the row's link (components/sf/fleet-search's capture handler). */
.sf-header .fs-pin{display:inline-grid;place-items:center;flex:0 0 26px;width:26px;height:26px;margin-left:auto;border-radius:var(--radius-xs);color:var(--text-3);cursor:pointer;opacity:0;transition:opacity var(--dur-hover) var(--ease-standard),background var(--dur-hover) var(--ease-standard)}
.sf-header .fs-row:hover .fs-pin,.sf-header .fs-row:focus-within .fs-pin,.sf-header .fs-row.is-focus .fs-pin,.sf-header .fs-pin:focus-visible{opacity:1}
.sf-header .fs-pin:hover{background:var(--surface-2);color:var(--text)}
.sf-header .fs-pin:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.sf-header .fs-pin.is-on{opacity:1;color:var(--accent-text);background:var(--highlight)}
@media (hover:none){.sf-header .fs-pin{opacity:1}}
/* a filter on: the Fleet button names it in accent (compact header: the ship turns accent) */
.sf-header .fs-trigger.is-filtered{color:var(--accent-text);border-color:color-mix(in srgb,var(--accent) 35%,var(--glass-border))}
.sf-header .fs-filter-on{display:inline-flex;align-items:center;gap:5px;min-width:0;max-width:120px}
.sf-header .fs-filter-on__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-header .fs-trigger.is-filtered>.sf-row{min-width:0}

/* ---------- Manage assets (pilot page): toolbar, search suggestions, loading bar, skeletons ---------- */
.sf-al-toolbar{align-items:center}
.sf-al-search{position:relative;flex:1 1 280px;min-width:220px;max-width:520px}
.sf-al-search>.sf-btn-icon{position:absolute;right:6px;top:50%;transform:translateY(-50%)}
.sf-al-filter{flex:0 1 200px;min-width:160px}
.sf-suggest{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:60;display:flex;flex-direction:column;padding:6px;border-radius:var(--radius-lg);
  background:var(--surface-elevated);border:1px solid var(--border);box-shadow:var(--shadow-e2)}
.sf-suggest__item{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:var(--space-3);padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;color:var(--text);font:var(--ui-body)}
.sf-suggest__item:hover,.sf-suggest__item.is-focus{background:var(--surface-2)}
.sf-suggest__item:focus-visible{box-shadow:var(--focus-ring)}
.sf-suggest__text{display:flex;flex-direction:column;min-width:0}
.sf-suggest__name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-suggest__meta{font:var(--ui-meta);color:var(--text-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-suggest mark{background:var(--highlight);color:inherit;border-radius:2px}
.sf-al-bar{height:2px;background:transparent;overflow:hidden}
.sf-al-bar.is-on{background:var(--divider)}
.sf-al-bar.is-on::after{content:"";display:block;height:100%;width:35%;background:var(--accent);animation:sf-al-slide 1s linear infinite}
@keyframes sf-al-slide{from{transform:translateX(-100%)}to{transform:translateX(300%)}}
.sf-al-skeleton{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4)}
.sf-al-skeleton.is-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--space-6);padding:0}
.sf-al-skeleton .sf-row{flex-wrap:nowrap}
.sf-al-vessel{display:flex;align-items:center;gap:var(--space-3);min-width:0}
.sf-al-vessel .sf-avatar{flex:none}
.sf-al-vessel__text{display:flex;flex-direction:column;min-width:0}
.sf-al-name{font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
a.sf-al-name:hover{color:var(--accent-text);text-decoration:none}
.sf-al-card{display:flex;flex-direction:column;gap:var(--space-4)}
.sf-al-card__top{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-3)}
.sf-al-card__foot{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-top:auto}
.sf-al-stat{display:inline-flex;align-items:center;gap:6px;color:var(--text-2);font:var(--ui-body)}
.sf-al-foot{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--space-3);margin-top:var(--space-4)}
.sf-al-error{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);color:var(--error-text)}
.sf-al-person{display:inline-flex;align-items:center;gap:var(--space-2);min-width:0}
.sf-al-person__text{display:flex;flex-direction:column;min-width:0}

/* ---------- Guide Studio (guide-studio/*, 2026-10-15) ---------- */
/* the guides map: menu › page › tab header rows over the guide rows, menus fold like the sidebar (index script builds them) */
.gs-guides tr.gs-tree-h td{padding-top:var(--space-3);padding-bottom:4px;border-bottom:0;background:transparent}
.gs-guides tr.gs-tree-h:hover td{background:transparent}
.gs-tree-block td,.gs-tree-page td,.gs-tree-tab td{font:var(--ui-meta);color:var(--text-2)}
.gs-tree-block td{font-weight:600;letter-spacing:.02em}
.gs-guides .gs-tree-page td{padding-left:28px}
.gs-guides .gs-tree-tab td{padding-left:44px}
.gs-tree-toggle{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:var(--space-2);width:100%;padding:4px 0;font:var(--ui-label);font-weight:600;color:var(--text);cursor:pointer}
.gs-tree-toggle:focus-visible{box-shadow:var(--focus-ring);border-radius:var(--radius-xs)}
.gs-tree-toggle::before{content:"";width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);opacity:.6;transition:transform var(--dur-fast) var(--ease-standard)}
.gs-tree-toggle[aria-expanded="true"]::before{transform:rotate(45deg)}
.gs-help-count{font:var(--ui-meta);font-variant-numeric:tabular-nums;color:var(--text-2)}
.gs-guides tr.gs-tree-leaf td:first-child{padding-left:40px}
.gs-guides tr.gs-tree-leaf-tab td:first-child{padding-left:56px}
/* the editor: a step's picture (the annotated crop the PDF and the tour use) */
.gs-thumb{display:block;width:240px;aspect-ratio:3/2;height:auto;object-fit:contain;background:color-mix(in srgb,var(--text) 8%,transparent);border-radius:var(--radius-sm);border:1px solid var(--divider);filter:var(--photo-dim,none)}
.gs-video-preview{display:block;width:100%;max-width:480px;border-radius:var(--radius-md);background:var(--surface-solid)}
.gs-step-text{white-space:normal;min-width:240px}
.gs-up .sf-icon{transform:rotate(180deg)}   /* Move up = the expand chevron turned over */
/* a form among row actions (Publish / Edit again posts) takes no box of its own */
.sf-row-actions>form{display:contents}
/* a full table's toolbar fills its row, so an end group (.sf-cert-toolbar__end) reaches the right edge */
.sf-dtable__tools{flex:1 1 auto}

/* ---------- Activity Log (admin/activity-log, 2026-10-15) ---------- */
/* an entry's details in the pop-up: its properties as indented JSON, on the field tint, scrolling inside */
.sf-al-json{margin:0;max-height:60vh;overflow:auto;padding:var(--space-4);border-radius:var(--radius-md);background:color-mix(in srgb,var(--field) 55%,transparent);border:1px solid var(--divider);
  color:var(--text);font:400 12px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}
.sf-al-time{white-space:nowrap}   /* the time never wraps (the table scrolls sideways on a phone) */

/* ---------- Settings frame (x-sf.settings-shell, Settings › General 2026-10-15) ---------- */
.sf-settings{display:grid;grid-template-columns:240px minmax(0,1fr);gap:var(--space-6);align-items:start}
.sf-settings.is-single{grid-template-columns:minmax(0,1fr)}
.sf-settings__nav{position:sticky;top:calc(64px + var(--space-8));padding:var(--space-2);display:flex;flex-direction:column;gap:2px}
.sf-settings__nav .sf-nav-item{text-decoration:none}
.sf-settings__fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5)}
.sf-settings__fields>.is-wide{grid-column:1/-1}
/* a picture the settings page owns (client logo): rounded square, the crop window paints it (photo-crop.js sets background-image) */
.sf-settings-identity{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--space-6);align-items:center}
.sf-settings-logo{width:96px;height:96px;border-radius:var(--radius-lg);border:1px solid var(--divider);background:var(--field) var(--logo,none) center/cover no-repeat}
.sf-settings-logo.is-round{border-radius:50%}
.sf-settings-identity__text{display:flex;flex-direction:column;gap:var(--space-2);min-width:0;overflow-wrap:anywhere}
@media (max-width:1023px){
  .sf-settings{grid-template-columns:minmax(0,1fr)}
  .sf-settings__nav{position:relative;top:auto;flex-direction:row;overflow-x:auto;scrollbar-width:none}
  .sf-settings__nav .sf-nav-item{flex:none;width:auto}
}
@media (max-width:639px){.sf-settings__fields,.sf-settings-identity{grid-template-columns:1fr}}

/* ---------- Employee form (pilot, Task 15) ---------- */
/* Person card (owner 2026-10-20, option C): photo, the name / email as typed, the sections as a status list; on top of the form below 1280 px */
.sf-emp-person{position:sticky;top:calc(64px + var(--space-8));align-self:start}
.sf-emp-person__body{display:flex;flex-direction:column;align-items:center;gap:var(--space-4)}
.sf-emp-person__id{display:flex;flex-direction:column;align-items:center;gap:2px;max-width:100%;text-align:center}
.sf-emp-person__id>*{max-width:100%;overflow-wrap:anywhere}
.sf-emp-person .sf-status-list{align-self:stretch;margin:0;padding:var(--space-3) 0 0;border-top:1px solid var(--divider);list-style:none}
.sf-emp-person .sf-status-list__row{text-decoration:none}
@media (max-width:1279px){.sf-emp-person{position:static}}
.sf-emp-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5)}
.sf-emp-fields>.is-wide{grid-column:1/-1}
@media (max-width:639px){.sf-emp-fields{grid-template-columns:1fr}}
.sf-emp-photo{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);text-align:center}
.sf-emp-photo .sf-avatar{background-size:cover;background-position:center}
.sf-emp-photo .sf-avatar.has-photo .sf-avatar__initials{display:none}
.sf-emp-phone{display:grid;grid-template-columns:120px minmax(0,1fr);gap:var(--space-2)}
.sf-emp-list{display:flex;flex-direction:column}
.sf-emp-list__row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);padding:var(--space-3) 0;border-top:1px solid var(--divider)}
.sf-emp-list__row:first-child{border-top:0}
.sf-emp-list__text{display:flex;flex-direction:column;min-width:0}
.sf-emp-list__text b{font:var(--ui-label);color:var(--text)}
.sf-emp-foot{display:flex;justify-content:flex-end;align-items:center;gap:var(--space-3)}
.sf-emp-flag{flex:none;width:16px;height:16px;border-radius:50%;object-fit:cover}   /* in .sf-select-person: the row's gap spaces it */

/* ---------- Dashboard (pilot, Task 16): section labels, panel filter row, crew meters, news list, crew modal ---------- */
.sf-dash{--gap:var(--space-8)}
.sf-dash-slot{display:flex;min-width:0}.sf-dash-slot>*{flex:1;min-width:0}
/* phone: counters 2 per row, as .sf-grid.is-kpis (base.css); every other slot spans both columns */
@media (max-width:639px){.sf-dash-board{--cols:2}.sf-dash-board>.sf-dash-slot.is-kpi{grid-column:auto}.sf-dash-board>.sf-dash-slot.is-kpi-wide{grid-column:1/-1}
  .sf-dash-slot.is-kpi>.sf-kpi{padding:var(--space-4);gap:var(--space-1)}.sf-dash-slot.is-kpi .sf-kpi__label{font-size:11px}}

/* ---------- Dashboard board (spec 2026-11-07 own layout): Customize mode = dashed outlines + the controls (grip and hide / ⋯ on the
   top edge, resize corner on the bottom edge: they sit on the frame, never over the card), the tray strip above the board. No wobble; the drag lifts with --m-lift as .sf-sort__row. The controls
   exist only in .is-edit and never wait for a hover (touch). Height steps: chart is-h2 = 440 px, is-h3 = 600 (default 260); list is-h1 = card at most 320 px, is-h3 = at least 600. ---------- */
.sf-dash-slot{position:relative;transition:scale var(--m-up)}
.sf-dash-slot.is-h2[data-dash-kind=chart]{--sad-chart-h:440}   /* read by SadCharts at mount and by SadCharts.fit (the board's Height step) */
.sf-dash-slot.is-h3[data-dash-kind=chart]{--sad-chart-h:600}
/* list Compact: the card is capped, its head stays and what follows scrolls; Tall: at least 600 px */
.sf-dash-slot.is-h1[data-dash-kind=list]>.sf-card{display:flex;flex-direction:column;max-height:320px;overflow:hidden}
.sf-dash-slot.is-h1[data-dash-kind=list]>.sf-card>:not(.sf-card__head){flex:1 1 auto;min-height:0;overflow:auto}
.sf-dash-slot.is-h3[data-dash-kind=list]{min-height:600px}
@media (max-width:639px){.sf-dash-slot.is-no-phone{display:none}}
/* Customize mode: a card hidden on phone stays reachable below 640 px, dimmed, with a badge (its tools stay fully visible) */
@media (max-width:639px){
  .sf-dash-board.is-edit>.sf-dash-slot.is-no-phone{display:flex}
  .sf-dash-board.is-edit>.sf-dash-slot.is-no-phone>:not(.sf-dash-tools,.sf-dash-corner){opacity:.38}
  .sf-dash-board.is-edit>.sf-dash-slot.is-no-phone::after{content:"Not on phone";position:absolute;z-index:4;top:var(--space-2);left:var(--space-2);display:inline-flex;align-items:center;height:22px;padding:0 8px;border-radius:var(--radius-pill);
    font:var(--ui-meta);font-weight:600;background:var(--surface-2);border:1px solid var(--border);color:var(--text-2);white-space:nowrap;pointer-events:none}
}
.sf-dash-tools,.sf-dash-corner{display:none}
.sf-dash-board.is-edit{row-gap:var(--space-12)}   /* the corner of one card and the tools of the card below never touch (18 + 18 px < 48) */
.sf-dash-board.is-edit>.sf-dash-slot{outline:1px dashed var(--text-3);outline-offset:4px;border-radius:var(--radius-xl)}
.sf-dash-board.is-edit>.sf-dash-slot>:not(.sf-dash-tools,.sf-dash-corner){pointer-events:none;user-select:none}
.sf-dash-board.is-edit .sf-dash-tools{display:flex;position:absolute;z-index:5;inset:-18px 12px auto;align-items:center;justify-content:space-between;gap:var(--space-1)}
.sf-dash-tools__end{display:flex;gap:var(--space-1)}
.sf-dash-tool{all:unset;box-sizing:border-box;display:inline-grid;place-items:center;width:28px;height:28px;border-radius:var(--radius-pill);cursor:pointer;
  color:var(--text-2);background:var(--surface-elevated);border:1px solid var(--divider);transition:background var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-dash-tool:hover{background:var(--surface-2);color:var(--text)}
.sf-dash-tool:focus-visible{box-shadow:var(--focus-ring)}
.sf-dash-grip{cursor:grab;touch-action:none}
.sf-dash-corner .sf-icon{rotate:-45deg}   /* the chevron points at the corner */
.sf-dash-board.is-edit .sf-dash-corner{display:inline-grid;position:absolute;z-index:5;right:12px;bottom:-18px;cursor:nwse-resize;touch-action:none}
.sf-dash-board.is-edit>.sf-dash-slot.is-lifted{z-index:6;scale:var(--m-lift);outline-style:solid;transition:scale var(--m-slide) var(--ease-standard)}
.sf-dash-slot.is-lifted .sf-dash-grip{cursor:grabbing}
/* Studio preview (?studio=1, sofonn-dashboard-preview.js): the cards take no pointer (a click selects, a drag reorders), the selected one is outlined.
   .is-phone-preview = the phone frame: at 390 px the phone rules above (2 KPIs per row, is-no-phone) already apply; the class keeps phone:false cards out at any width. */
.sf-dash-board.is-studio>.sf-dash-slot>*{pointer-events:none;user-select:none}
.sf-dash-board.is-studio:not(.is-phone-preview)>.sf-dash-slot{cursor:grab}
.sf-dash-board.is-studio>.sf-dash-slot.is-selected{outline:2px solid var(--accent);outline-offset:4px;border-radius:var(--radius-xl)}
.sf-dash-board.is-studio>.sf-dash-slot.is-lifted{z-index:6;scale:var(--m-lift);cursor:grabbing;transition:scale var(--m-slide) var(--ease-standard)}
.sf-dash-board.is-phone-preview>.sf-dash-slot.is-no-phone{display:none}
/* the desktop preview has no sidebar (bare): its column stays empty, so the cards keep the real dashboard's width at 1440 */
@media (min-width:1280px){.sf-shell:not(:has(.sf-sidebar)):has(.sf-dash-board.is-studio) .sf-main{grid-column:2}}
.sf-dash-slot.is-menu{z-index:30}
.sf-dash-menu{min-width:220px}
.sf-dash-menu .sf-menu__item:disabled{opacity:.38;cursor:default;background:none}
.sf-dash-menu__label{padding:6px 10px 2px;font:var(--ui-meta);color:var(--text-3)}
.sf-dash-choices{display:flex;gap:2px;padding:0 4px 4px}
.sf-dash-choices button{all:unset;box-sizing:border-box;flex:1;height:28px;padding:0 8px;border-radius:var(--radius-sm);text-align:center;font:600 12px/28px var(--font-sans);color:var(--text-2);cursor:pointer;transition:background var(--dur-hover) var(--ease-standard)}
.sf-dash-choices button:hover{background:var(--surface-2);color:var(--text)}
.sf-dash-choices button[aria-pressed="true"]{background:var(--surface-2);color:var(--text);box-shadow:inset 0 0 0 1px var(--border-strong)}
.sf-dash-choices button:focus-visible{box-shadow:var(--focus-ring)}
.sf-dash-edit{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3);margin-bottom:var(--space-8);padding:var(--space-3) var(--space-4);border-radius:var(--radius-xl);border:1px dashed var(--border-strong)}
.sf-dash-tray{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);flex:1 1 20rem;min-width:0}
.sf-dash-tray__list{display:contents}
.sf-dash-chip{all:unset;box-sizing:border-box;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:inline-flex;align-items:center;gap:6px;height:var(--control-sm);padding:0 12px;border-radius:var(--radius-pill);border:1px solid var(--border);
  font:var(--ui-label);color:var(--text-2);cursor:pointer;transition:background var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard)}
.sf-dash-chip:hover{background:var(--surface-2);color:var(--text)}
.sf-dash-chip:focus-visible{box-shadow:var(--focus-ring)}
.sf-dash-edit__actions{display:flex;gap:var(--space-2);margin-left:auto}
.sf-dash-label{white-space:nowrap;font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-2)}
.sf-dash .sf-card__head,.sf-dash .sf-card__actions{flex-wrap:wrap}
.sf-dash-ctx{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin-bottom:var(--space-4)}
.sf-dash-pick{display:inline-block;width:170px;max-width:100%}
.sf-dash-date{font:400 13px/1.2 var(--font-sans);white-space:nowrap}
/* Compact controls (owner 2026-10-09: filters were too big): any field in a filter row inside a card (.sf-dash-ctx, .sf-filters)
   and any filter or switch in a card header (.sf-card__actions) is 32 px, 13 px text. Forms and page-level controls stay 40 px. */
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-input{height:var(--control-sm);padding:0 12px;gap:8px;font-size:13px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-input input{font-size:13px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-input .sf-icon{width:16px;height:16px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-input--button{min-width:200px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-input--button::after{width:6px;height:6px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-select{height:var(--control-sm);padding:0 12px;font-size:13px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-segmented{height:var(--control-sm);padding:2px}
:is(.sf-dash-ctx,.sf-filters,.sf-card__actions) .sf-segmented__opt span{height:26px;padding:0 12px;font-size:12px}
.sf-dash-faces{all:unset;cursor:pointer;align-self:flex-start;border-radius:var(--radius-pill)}
.sf-dash-faces:focus-visible{box-shadow:var(--focus-ring)}
.sf-dash-meter{display:flex;justify-content:space-between;gap:var(--space-3);margin-top:var(--space-2)}
.sf-dash-chart{min-height:260px}
.sf-dash-story{display:flex;gap:var(--space-4);align-items:flex-start}
.sf-dash-cover{width:160px;height:110px;object-fit:cover;border-radius:var(--radius-lg);flex:none}
@media (max-width:639px){.sf-dash-story{flex-direction:column}.sf-dash-cover{width:100%;height:160px}}
.sf-dash-news{display:flex;flex-direction:column}
.sf-dash-news__row{display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--divider);color:var(--text)}
.sf-dash-news li:first-child .sf-dash-news__row{border-top:0;padding-top:0}
.sf-dash-news__row:hover{text-decoration:none}
.sf-dash-news__row:hover .sf-dash-news__title{color:var(--accent-text)}
.sf-dash-news__text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.sf-dash-news__title{font:var(--ui-label);color:var(--text)}
.sf-dash-news__excerpt{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.sf-dash-person{display:inline-flex;align-items:center;gap:var(--space-2);min-width:0;color:var(--text)}
.sf-dash-person:hover{text-decoration:none;color:var(--accent-text)}
/* ROB history (option B, 2026-10-30): the strip spans the card, two-line rows grow to fill it. The card stretches to its row's height. */
.sf-rob-card{display:flex;flex-direction:column}
.sf-rob-body{flex:1;min-height:0;display:flex;flex-direction:column;container-type:inline-size}
.sf-app .sad-daystrip.sf-rob-days{display:grid;grid-template-columns:repeat(11,minmax(0,1fr));gap:4px;overflow:visible;padding:0;margin:0 0 var(--space-3);list-style:none}
.sf-app .sad-daystrip.sf-rob-days .sad-daystrip__item{flex:none;min-width:0}
.sf-app .sad-daystrip.sf-rob-days .sad-daystrip__pill{padding:6px 0}
@container (max-width:420px){.sf-app .sad-daystrip.sf-rob-days{gap:2px}.sf-app .sad-daystrip.sf-rob-days .sad-daystrip__day{font-size:10px}.sf-app .sad-daystrip.sf-rob-days .sad-daystrip__date{font-size:12px}}
.sf-rob-panes{flex:1;min-height:0;max-height:420px;overflow-y:auto;display:flex;flex-direction:column}
.sf-app .sf-dash-legacy .sf-rob-panes>.tab-pane.active{flex:1;display:flex;flex-direction:column}
.sf-rob-row{flex:1 1 60px;max-height:84px;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0;border-bottom:1px solid var(--divider)}
.sf-rob-row:last-child{border-bottom:0}
.sf-rob-row__main{flex:1;min-width:0}
.sf-rob-row__name{font:var(--ui-label);font-weight:600;color:var(--text)}
.sf-rob-row__nums{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.sf-rob-row__change{font:var(--ui-label);font-weight:600;font-variant-numeric:tabular-nums;color:var(--text)}
.sf-rob-row__change.is-plus{color:var(--success-text)}
.sf-rob-row__change.is-zero{color:var(--text-3);font-weight:500}
/* Fleet on hire (option C, 2026-10-29): trend left, the vessels behind it right; stacked below 900 px */
.sf-dash-hire{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:var(--space-5);align-items:start}
.sf-dash-hire>*{min-width:0}
@media (max-width:899px){.sf-dash-hire{grid-template-columns:1fr}}
.sf-dash-hire__list{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-dash-hire__foot{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--space-2);font:400 13px/1.4 var(--font-sans)}
.sf-dash-hire__off summary{cursor:pointer;color:var(--text-2)}
.sf-dash-hire__off summary:focus-visible{box-shadow:var(--focus-ring);border-radius:4px;outline:0}
.sf-dash-hire__off ul{list-style:none;margin:var(--space-2) 0 0;padding:0;display:flex;flex-direction:column;gap:4px;color:var(--text-2)}
.sf-dash-hire__off li{display:flex;align-items:center;gap:var(--space-2)}
.sf-dash-hire__all{margin-left:auto;white-space:nowrap}

/* ---------- Glass inside glass (owner 2026-10-09) ----------
   A backdrop-filter element is a backdrop root: anything blurred INSIDE it (a menu in the header, a side panel in a menu,
   a kebab menu in a card) can only blur what is inside its parent, not the page, so it looked see-through; it is also the
   containing block of position:fixed children. So every glass surface paints its glass on a ::before layer behind its
   content and the element itself carries no backdrop-filter: dropdowns inside the header / cards get the real header blur.
   Values unchanged: --glass-fill, blur --glass-blur + saturate --glass-saturate (border and shadow stay on the element). */
.sf-glass,.sf-card,.sf-kpi,.sf-dtable,.sf-menu__panel{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;isolation:isolate}
.sf-kpi,.sf-dtable{position:relative}   /* page tab bars keep the blur on the element: they scroll sideways on phones and hold no menus */
.sf-glass::before,.sf-card::before,.sf-kpi::before,.sf-dtable::before,.sf-menu__panel::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
.sf-card .sf-card::before,.sf-card .sf-kpi::before{background:color-mix(in srgb,var(--glass-fill) 35%,transparent);-webkit-backdrop-filter:none;backdrop-filter:none}
/* Menus, pop-overs (Filters, Export, kebabs, account), dropdown lists and calendars float over content: they stay glass (blur)
   but on a dense fill in every theme and glass mode, so their text and fields read over a table or the wallpaper (owner
   2026-10-15: "the filter … so glass and not legible"; Clear made them 32-45 % opaque). One token: --menu-fill. */
:root{--menu-fill:color-mix(in srgb,var(--surface-elevated) 90%,transparent)}
.sf-menu__panel::before{background:var(--menu-fill)}
/* isolation makes every glass card its own stacking layer, so an open menu could not rise above the NEXT card (Tank reports
   Export, 2026-10-13): the card that holds an open menu rises above its siblings while it is open. */
:is(.sf-card,.sf-kpi,.sf-dtable):has(.sf-menu__panel:not([hidden])){z-index:20}   /* content cards only (all position:relative): never the
   header / sidebar — the header's Fleet search panel has no [hidden], so a .sf-glass rule here matched the header always and
   took its sticky position + z-index 50 (owner 2026-10-13: "the header is broken … it hides completely") */
.sf-glass .sf-glass::before{background:var(--surface-2);-webkit-backdrop-filter:none;backdrop-filter:none}
@media (max-width:639px){.sf-menu__panel.sf-submenu__panel{position:relative;inset:auto}.sf-menu__panel.sf-submenu__panel::before{display:none}}   /* phone: the side panel sits inside its menu, under its row (inset:auto drops the desktop right:100% that pushed it off the screen and left a gap, owner 2026-10-22) */
/* ---------- Profile header (vessel / employee) — spec 2026-10-10-profile-headers ----------
   One card in exactly the header/sidebar glass (glass on ::before, see the glass-layer list below). Every value is set
   explicitly (h1, ul, a margins/fonts) because on old-layout pages Metronic's element rules are loaded too. */
.sf-ph{position:relative;display:flex;flex-direction:column;margin:0 0 var(--space-5);padding:var(--space-5) var(--space-6) 0;border-radius:var(--radius-xl);border:1px solid var(--glass-border);color:var(--text);font:var(--ui-body);min-width:0}
.sf-ph{background:transparent;isolation:isolate}   /* glass on its own ::before (like .sf-card), so menus inside blur the page */
.sf-ph::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
@media (prefers-reduced-transparency:reduce){.sf-ph::before{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--surface-elevated)}}
@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.sf-ph::before{background:var(--surface-elevated)}}   /* here, not base.css: old-layout pages load only tokens + components */
.sf-ph:has(.show){z-index:70}   /* an open ⋯ / crew list paints over the content below */
.sf-ph.is-collapsed{padding-top:0}
.sf-ph__body{display:flex;align-items:flex-start;gap:var(--space-4);padding-bottom:var(--space-4)}
.sf-ph.is-collapsed .sf-ph__body{display:none}
.sf-ph__photo{display:block;flex:none;border-radius:var(--radius-lg);text-decoration:none}
.sf-ph__photo .sf-avatar{border-radius:var(--radius-lg);font-size:22px}
.sf-ph__main{display:flex;flex-direction:column;gap:var(--space-2);flex:1;min-width:0}
.sf-ph__top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.sf-ph__name{margin:0;font:var(--ui-title);color:var(--text);letter-spacing:-.01em;min-width:0;overflow-wrap:anywhere}
.sf-ph__badge{display:inline-flex;color:var(--accent)}
.sf-ph__actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin-left:auto}
.sf-ph__menu{position:relative}
.sf-ph__menu .sf-menu__panel{display:none;margin:0}
.sf-ph__menu .sf-menu__panel.show{display:block}
.sf-ph__facts{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1) var(--space-4);margin:0;padding:0;list-style:none;color:var(--text-2);font:var(--ui-body)}
.sf-ph__fact{display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:360px}
.sf-ph__value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;color:var(--text);text-decoration:none}
a.sf-ph__value:hover{color:var(--accent-text);text-decoration:underline}
.sf-ph__value.is-empty{font-weight:500;color:var(--text-3)}
.sf-ph__value.is-warn{color:var(--warning-text)}
.sf-ph__sub{color:var(--text-3);white-space:nowrap}
.sf-ph__transit{animation:sf-ph-wave 1.5s var(--ease-standard) infinite}
@keyframes sf-ph-wave{50%{transform:translateY(-8%)}}
.sf-ph__nav{display:flex;align-items:center;gap:var(--space-2);margin:0 calc(-1 * var(--space-6));padding:var(--space-2) var(--space-6);border-top:1px solid var(--divider)}
.sf-ph.is-collapsed .sf-ph__nav{border-top:0}
/* the tab's own buttons at the right end of the tab row (owner 2026-10-19, TabActions): compact 32 px like the tabs; on a phone
   they drop under the tabs, inside the card */
.sf-ph__tab-actions{flex:none;margin-left:auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--space-2)}
/* the setup guide card (vessel Overview, vessel dashboard): on a phone Continue + × stay beside the title instead of a line of their own (owner 2026-10-22) */
@media (max-width:639px){.sf-app .sf-setup-bar .sf-card__actions{flex:0 0 auto;flex-wrap:nowrap}}
.sf-ph__tab-actions .sf-btn{--h:var(--control-sm);--px:12px}
.sf-ph__tab-actions :is(.sf-input,.sf-select){height:var(--control-sm);font-size:13px}
.sf-ph__tab-actions .sf-segmented{height:var(--control-sm);padding:2px}
/* every tab stays visible: when the buttons do not fit beside the tabs they wrap to a second line (right), the tabs never get cut
   (flex line breaking reads the tabs' own width, capped at the row minus the collapse toggle) */
.sf-ph__nav{flex-wrap:wrap}
.sf-ph__nav .sf-tab{padding:0 12px}   /* the small-button padding, so one button still fits beside eight tabs (vessel Technical) */
@media (max-width:767px){.sf-ph__tab-actions{width:100%;margin-left:0;justify-content:flex-start}}
/* one button in the tab row (Tanks & sensors: Done): it stays on the tabs' line and the tabs swipe beside it (owner 2026-10-22) */
@media (max-width:767px){.sf-ph__nav:has(>.sf-ph__tab-actions>:only-child){flex-wrap:nowrap}   /* never a :has() inside a :has(): invalid, the rule is dropped */
  .sf-ph__nav>.sf-ph__tab-actions:has(>:only-child){width:auto;margin-left:auto;flex:none}
  .sf-ph__nav>.sf-btn{flex:none}   /* the fold button keeps its 32 px on the one line */
  .sf-ph__nav:has(>.sf-ph__tab-actions>:only-child) .sf-tabs{max-width:none;overflow-x:auto;scrollbar-width:none}}
.sf-ph__nav .sf-tabs{flex:1 1 auto;max-width:calc(100% - 40px);min-width:0;padding:0;background:none;border:0;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none}
.sf-ph__toggle .sf-icon{transform:rotate(-90deg);transition:transform var(--dur-fast) var(--ease-standard)}
.sf-ph.is-collapsed .sf-ph__toggle .sf-icon{transform:rotate(90deg)}
.sf-tab.has-alert::after{content:"";width:6px;height:6px;border-radius:50%;background:var(--error);flex:none}
.sf-tab.has-alert .sf-tab__count{color:var(--error);opacity:1;font-weight:600}.sf-tab.has-alert:has(.sf-tab__count)::after{display:none}   /* a red count says it already (Templates, F-77) */
.sf-tab.is-hint{box-shadow:inset 0 0 0 1px var(--accent);animation:sf-tab-hint 1.6s var(--ease-standard) infinite}
@keyframes sf-tab-hint{50%{box-shadow:inset 0 0 0 2px var(--accent)}}
@media (prefers-reduced-motion:reduce){.sf-ph__transit,.sf-tab.is-hint{animation:none}}
@media (max-width:768px){
  .sf-ph{padding:var(--space-4) var(--space-4) 0}
  .sf-ph__photo .sf-avatar{width:44px;height:44px;font-size:18px}
  .sf-ph__actions{margin-left:0;width:100%}
  .sf-ph__fact{max-width:100%}
  .sf-ph__nav{margin:0 calc(-1 * var(--space-4));padding:var(--space-2) var(--space-4)}
}
/* ---------- Stepper (spec 2026-10-11-asset-stepper, layout B) ----------
   Bar on top (track + badge + title), one pane at a time on a 12-column grid, sticky footer. Works inside a pop-up on both
   layouts (old pages get this file from the component's loader; they have no base.css, hence the [hidden] guard). */
.sf-stepper{display:flex;flex-direction:column;min-width:0;position:relative}
.sf-stepper [hidden]{display:none!important}
.sf-stepper__bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:var(--space-3);margin:0 0 var(--space-5);padding:0;list-style:none}
.sf-stepper__seg{all:unset;box-sizing:border-box;display:flex;flex-direction:column;gap:var(--space-2);width:100%;cursor:pointer;border-radius:var(--radius-sm)}
.sf-stepper__seg:focus-visible{box-shadow:var(--focus-ring)}
.sf-stepper__track{height:4px;border-radius:4px;background:var(--divider);transition:background var(--dur-fast) var(--ease-standard)}
.sf-stepper__lab{display:flex;align-items:center;gap:var(--space-2);min-width:0;font:600 12px/1.2 var(--font-sans);color:var(--text-3)}
.sf-stepper__num{flex:none;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--text) 8%,transparent);color:var(--text-2);font:700 11px/1 var(--font-sans)}
.sf-stepper__title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-stepper__fix{font:var(--ui-meta);color:var(--error-text);white-space:nowrap}
.sf-stepper__seg.is-current .sf-stepper__track{background:var(--accent)}
.sf-stepper__seg.is-current .sf-stepper__lab{color:var(--text)}
.sf-stepper__seg.is-current .sf-stepper__num{background:var(--accent);color:var(--text-on-accent)}
.sf-stepper__seg.is-done .sf-stepper__track{background:color-mix(in srgb,var(--accent) 45%,transparent)}
.sf-stepper__seg.is-done .sf-stepper__num{background:var(--success-tint);color:var(--success-text);font-size:0}
.sf-stepper__seg.is-done .sf-stepper__num::after{content:"\2713";font:700 11px/1 var(--font-sans)}
.sf-stepper__seg.has-error .sf-stepper__track{background:var(--error)}
.sf-stepper__seg.has-error .sf-stepper__num{background:var(--error-tint);color:var(--error-text);font-size:0}
.sf-stepper__seg.has-error .sf-stepper__num::after{content:"!";font:700 11px/1 var(--font-sans)}
.sf-stepper__phone{display:none;margin:0 0 var(--space-4);align-items:center;gap:var(--space-3);font:700 13px/1.2 var(--font-sans);color:var(--text)}
.sf-stepper__dashes{display:flex;gap:6px;margin-left:auto}
.sf-stepper__dashes i{width:22px;height:4px;border-radius:4px;background:var(--divider)}
.sf-stepper__dashes i.is-current{background:var(--accent)}
.sf-stepper__dashes i.is-done{background:color-mix(in srgb,var(--accent) 45%,transparent)}
.sf-stepper__pane{display:none}
.sf-stepper__pane.is-current,.sf-stepper:not([data-ready]) .sf-stepper__pane:first-child{display:block}
.sf-stepper__head{margin:0 0 var(--space-4)}
.sf-stepper__h{margin:0;font:700 15px/1.3 var(--font-sans);color:var(--text)}
.sf-stepper__d{margin:2px 0 0;font:var(--ui-body);color:var(--text-2)}
.sf-stepper__grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--space-4) var(--space-4);align-items:start}
.sf-stepper__cell{grid-column:span var(--span,12);min-width:0}
.sf-stepper__foot{position:sticky;bottom:0;z-index:2;display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-5);padding:var(--space-3) 0;
  background:var(--surface-elevated);border-top:1px solid var(--divider)}
.sf-stepper__grow{flex:1}
.sf-stepper__count{font:var(--ui-meta);color:var(--text-3)}
.sf-stepper__photo{display:flex;align-items:center;gap:var(--space-4)}
/* the vessel photo preview at its saved shape (1360 × 800); the crop pop-up paints it (photo-crop.js), 2026-10-20 */
.sf-stepper__thumb{flex:none;display:grid;place-items:center;width:136px;aspect-ratio:1360/800;border-radius:var(--radius-md);
  border:1px solid var(--border);background:var(--field) var(--photo,none) center/cover no-repeat;color:var(--text-3)}
.sf-stepper__photo:not(.is-empty) .sf-stepper__thumb{filter:var(--photo-dim)}
.sf-stepper__photo:not(.is-empty) .sf-stepper__thumb .sf-icon{display:none}
.sf-stepper__photo-side{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
.sf-stepper__hint{font:var(--ui-meta);color:var(--text-3)}
.sf-stepper__ais{display:grid;place-items:center;height:150px;border:1px dashed var(--border-strong);border-radius:var(--radius-lg);color:var(--text-2)}
.sf-stepper__ais svg{width:140px;height:auto}
.sf-stepper__ais text{font:700 11px var(--font-sans);fill:var(--accent-text)}
.sf-stepper .sf-segmented{align-self:flex-start;max-width:100%} /* a flex item: inline-flex is blockified and would stretch */
/* Tagify (DP manufacturer / type) inside an x-sf.input: the field draws the box, the tag is a calm chip */
.sf-input .tagify{flex:1;min-width:0;border:0;background:none;padding:0;font:400 14px/1.2 var(--font-sans);--tags-border-color:transparent;--tags-hover-border-color:transparent;--tags-focus-border-color:transparent;--tag-bg:var(--surface-2);--tag-hover:var(--surface-2);--tag-text-color:var(--text);--tag-pad:3px 8px;--tag-inset-shadow-size:0;--tag-remove-btn-color:var(--text-3)}
.sf-input .tagify__input{margin:0;padding:0 4px;color:var(--text)}
.sf-input .tagify__tag>div{padding:var(--tag-pad);font:500 13px/1.3 var(--font-sans)}
.sf-input .tagify:not(.form-control-sm):not(.form-control-lg) .tagify__tag .tagify__tag-text{font:500 13px/1.3 var(--font-sans)}
/* a field the browser or the server refused: red frame + red help (the class lands on the inner input / select) */
.sf-field:has(.is-invalid) .sf-input,.sf-field.is-error .sf-input{border-color:var(--error-text);box-shadow:0 0 0 3px var(--error-tint)}
.sf-field:has(.is-invalid) .sf-field-help{color:var(--error-text)}
.sf-field.is-error .select2-selection{border-color:var(--error-text)!important;box-shadow:0 0 0 3px var(--error-tint)}
@media (prefers-reduced-motion:reduce){.sf-stepper__track{transition:none}}
@media (max-width:640px){.sf-stepper__bar{display:none}.sf-stepper__phone{display:flex}.sf-stepper__cell{grid-column:1/-1}}
.sf-input__unit{flex:none;font:var(--ui-meta);color:var(--text-3)}
.sf-input input[type="color"]{-webkit-appearance:none;appearance:none;flex:none;width:28px;height:22px;padding:0;border-radius:6px;cursor:pointer}
.sf-input input[type="color"]::-webkit-color-swatch-wrapper{padding:0}
.sf-input input[type="color"]::-webkit-color-swatch{border:1px solid var(--glass-border);border-radius:6px}
/* Search-and-pick field (x-sf.combobox, owner option A 2026-11-06): an x-sf.input with a chevron; its list = the select2 list's values */
.sf-combo{cursor:text}
.sf-combo .sf-combo__chev{width:16px;height:16px;color:var(--text-3);pointer-events:none}
.sf-combo__new{flex:none;padding:3px 7px;border-radius:var(--radius-pill);background:var(--warning-tint);color:var(--warning-text);font:var(--ui-meta)}
.sf-combo__clear{all:unset;flex:none;display:grid;place-items:center;width:24px;height:24px;border-radius:6px;color:var(--text-3);cursor:pointer}
/* all:unset beats the browser's [hidden]; old-layout pop-ups (sections/sf-popup-assets) have no base.css to cover it. */
.sf-combo__clear[hidden]{display:none!important}
.sf-combo__clear:hover{background:var(--surface-2);color:var(--text)}
.sf-combo__clear:focus-visible{box-shadow:var(--focus-ring)}
.sf-combo__clear .sf-icon{width:16px;height:16px}
/* multiple: chips wrap inside the field, which grows by rows (several issuers, owner 2026-11-06) */
.sf-combo.is-multi{flex-wrap:wrap;height:auto;min-height:var(--control-md);padding:5px 10px;gap:6px}
.sf-combo.is-multi input{flex:1 0 120px;min-height:28px}
.sf-combo.is-multi .sf-combo__chev{align-self:center}
.sf-combo__chip{display:inline-flex;align-items:center;gap:4px;max-width:100%;height:28px;padding:0 4px 0 10px;border:1px solid var(--glass-border);border-radius:var(--radius-pill);background:var(--surface-2);color:var(--text);font:500 13px/1 var(--font-sans)}
.sf-combo__chip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-combo__chip.is-new{background:var(--warning-tint);color:var(--warning-text);border-color:transparent}
.sf-combo__chip-x{all:unset;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;color:currentColor;opacity:.7;cursor:pointer;font:400 16px/1 var(--font-sans)}
.sf-combo__chip-x:hover{opacity:1;background:var(--surface-2)}
.sf-combo__chip-x:focus-visible{opacity:1;box-shadow:var(--focus-ring)}
.sf-combo__menu{position:fixed;z-index:1090;display:flex;flex-direction:column;gap:2px;overflow-y:auto;padding:6px;background:var(--menu-fill);border:1px solid var(--glass-border);border-radius:var(--radius-lg);
  -webkit-backdrop-filter:blur(48px) saturate(180%);backdrop-filter:blur(48px) saturate(180%);box-shadow:var(--shadow-e3)}
.sf-combo__opt{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);flex:none;min-height:36px;padding:0 12px;border-radius:var(--radius-sm);font:400 14px/1.3 var(--font-sans);color:var(--text);cursor:pointer}
.sf-combo__opt.is-active{background:var(--surface-2)}
.sf-combo__opt.is-selected{background:var(--highlight);color:var(--accent-text)}
.sf-combo__opt.is-selected::after{content:"";flex:none;width:9px;height:5px;border-left:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(-45deg)}
.sf-combo__opt.is-add{color:var(--accent-text);font-weight:500;border-top:1px solid var(--divider);border-radius:0 0 var(--radius-sm) var(--radius-sm)}
.sf-combo__opt.is-add:not(:first-child){margin-top:4px}
.sf-combo__opt.is-add:first-child{border-top:0;border-radius:var(--radius-sm)}
.sf-combo__opt.is-empty{color:var(--text-3);cursor:default;white-space:normal;padding:8px 12px}
.sf-combo__keys{display:flex;gap:4px}
.sf-combo__keys kbd{min-width:20px;padding:2px 6px;border:1px solid var(--border-strong);border-radius:5px;background:var(--surface-2);color:var(--text-2);font:500 11px/1.3 var(--font-sans);text-align:center}
.sf-input input[type="color"]::-moz-color-swatch{border:1px solid var(--glass-border);border-radius:6px}

/* ---------- Pop-up frame on old pages (spec 2026-10-11-certificate-popups §2) ----------
   Our pop-ups (form sheet, stepper) mark their modal .sf-popup: the frame is the header/sidebar glass in light and dark
   even where the page has no .sf-app (compat.css draws the same frame on the new pages). */
.modal.sf-popup .modal-content{position:relative;isolation:isolate;display:flex;flex-direction:column;max-height:calc(100vh - 2 * var(--space-12));border:1px solid var(--glass-border);border-radius:var(--radius-xl);background:transparent;box-shadow:var(--shadow-e2);color:var(--text);overflow:hidden}
.modal.sf-popup .modal-content::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate))}
@media (prefers-reduced-transparency:reduce){.modal.sf-popup .modal-content::before{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--surface-elevated)}}
/* ---------- Pop-up form sheet + rows (layout A) ---------- */
.sf-sheet{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;color:var(--text)}
.sf-sheet [hidden]{display:none!important}
.sf-sheet__head{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-6);border-bottom:1px solid var(--divider)}
.sf-sheet__icon{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:10px;background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text);font:700 13px/1 var(--font-sans)}
.sf-sheet__title{margin:0;font:700 15px/1.25 var(--font-sans);color:var(--text)}
.sf-sheet__sub{margin:2px 0 0;font:var(--ui-meta);color:var(--text-2)}
.sf-sheet__chip{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:var(--radius-pill);font:600 11px/1 var(--font-sans);background:color-mix(in srgb,var(--text) 8%,transparent);color:var(--text-2);white-space:nowrap}
.sf-sheet__chip i{width:6px;height:6px;border-radius:50%;background:var(--dot,var(--text-3))}
.sf-sheet__chip.is-ok i{background:var(--success-text)}.sf-sheet__chip.is-warn i{background:var(--warning-text)}.sf-sheet__chip.is-error i{background:var(--error-text)}
/* a toned chip = the table's state badge (.sf-badge.is-*): tint + text, so "Vacant" reads the same amber in the sheet and the list */
.sf-sheet__chip.is-ok{background:var(--success-tint);color:var(--success-text)}.sf-sheet__chip.is-warn{background:var(--warning-tint);color:var(--warning-text)}.sf-sheet__chip.is-error{background:var(--error-tint);color:var(--error-text)}
.sf-sheet__grow{flex:1}
.sf-sheet__form{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;margin:0}
.sf-sheet__body{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--space-4) var(--space-6)}
.sf-sheet__body>.sf-table-wrap{margin-bottom:var(--space-4)}   /* a table in a sheet (a conflict's values) keeps the rows' spacing below it */
.sf-sheet__body>.sf-alert:not(:last-child){margin-bottom:var(--space-4)}   /* a notice above the rows (Rotation work period, 2026-10-19) */
.sf-sheet__foot{position:sticky;bottom:0;display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-6);border-top:1px solid var(--divider);background:color-mix(in srgb,var(--surface-elevated) 70%,transparent)}
/* Page variant (F-49, owner 2026-10-19): a full-page form keeps its one Save in sight while scrolling — the sheet's footer as a glass bar
   held 16 px above the window bottom (last child of the <form>; Cancel ghost · grow · one primary + its shortcut) */
.sf-sheet__foot--page{bottom:var(--space-4);z-index:20;padding:var(--space-3) var(--space-4);border:1px solid var(--glass-border);border-radius:var(--radius-lg);
  background:var(--glass-fill);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));box-shadow:var(--shadow-e2)}
.sf-frow{display:grid;grid-template-columns:190px minmax(0,1fr);gap:var(--space-4);padding:var(--space-4) 0;border-top:1px solid var(--divider)}
.sf-frow:first-of-type{border-top:0;padding-top:var(--space-1)}
.sf-frow__t{margin:0;font:700 13px/1.3 var(--font-sans);color:var(--text)}
.sf-frow__label:has(>.sf-info)>.sf-frow__t{display:inline}.sf-frow__label>.sf-info{margin-left:2px}   /* <x-slot:info>: the ⓘ beside the title */
.sf-frow__h{margin:2px 0 0;font:var(--ui-meta);color:var(--text-2)}
.sf-frow__h.is-error{color:var(--error-text);font-weight:600}
.sf-frow__body{min-width:0}
.sf-frow__now{display:flex;flex-wrap:wrap;gap:var(--space-5);font:var(--ui-meta);color:var(--text-2)}
.sf-frow__now b{display:block;margin-top:2px;font:600 13px/1.3 var(--font-sans);color:var(--text)}
.sf-switch-row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:9px 0;border-top:1px solid var(--divider);font:500 13px/1.3 var(--font-sans);color:var(--text);cursor:pointer}
.sf-switch-row:first-child{border-top:0;padding-top:0}
.sf-switch{-webkit-appearance:none;appearance:none;flex:none;position:relative;width:34px;height:20px;margin:0;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--text) 18%,transparent);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard)}
.sf-switch::before{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--bg-raised);box-shadow:0 1px 2px color-mix(in srgb,var(--text) 25%,transparent);transition:left var(--dur-fast) var(--ease-standard)}
.sf-switch:checked{background:var(--accent)}
.sf-switch:checked::before{left:16px}
.sf-switch:disabled{cursor:default;opacity:.75}
.sf-switch:focus-visible{outline:none;box-shadow:var(--focus-ring)}
@media (pointer:coarse){.sf-switch{width:40px;height:24px}.sf-switch::before{width:20px;height:20px}.sf-switch:checked::before{left:18px}}   /* touch: 24 px minimum target */
.sf-files{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-files__drop{position:relative;display:flex;align-items:center;gap:var(--space-3);padding:12px 14px;border:1px dashed var(--border-strong);border-radius:var(--radius-md);font:var(--ui-body);color:var(--text-2);cursor:pointer}
.sf-files__drop b{color:var(--accent-text);font-weight:600}
.sf-files__drop:hover{background:color-mix(in srgb,var(--text) 4%,transparent)}
.sf-files__input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.sf-files__chips{display:flex;flex-wrap:wrap;gap:6px}
.sf-files__chip{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 4px 0 10px;border-radius:8px;background:color-mix(in srgb,var(--text) 7%,transparent);font:500 12px/1 var(--font-sans);color:var(--text)}
.sf-files__x{all:unset;cursor:pointer;width:18px;height:18px;display:grid;place-items:center;border-radius:50%;color:var(--text-3)}
.sf-files__x:hover{color:var(--text);background:color-mix(in srgb,var(--text) 8%,transparent)}
.sf-files__on-file{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px;font:var(--ui-meta)}
.sf-files__on-file li{display:flex;gap:var(--space-2)}
.sf-files__on-file a{color:var(--accent-text);text-decoration:none}
.sf-files__on-file span{color:var(--text-3)}
.sf-files.is-error .sf-files__drop,.sf-field.is-error .sf-files__drop{border-color:var(--error-text)}
@media (max-width:640px){.sf-frow{grid-template-columns:minmax(0,1fr);gap:var(--space-2)}.sf-sheet__head,.sf-sheet__body,.sf-sheet__foot{padding-left:var(--space-4);padding-right:var(--space-4)}}

/* Stand-by · this week (dashboard Operation tab): three stats + one bar per day, accent bars, calm */
.sf-standby{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:var(--space-6);margin-bottom:var(--space-3)}
.sf-standby__stats{display:flex;flex-wrap:wrap;gap:var(--space-8);margin:0}
.sf-standby__stats dt{font:var(--ui-meta);color:var(--text-2)}
.sf-standby__stats div{display:flex;flex-direction:column-reverse;gap:var(--space-1)}
.sf-standby__stats dd{margin:0;font:var(--ui-stat);letter-spacing:var(--track-kpi);color:var(--text)}
.sf-standby__stats small{font:var(--ui-label);color:var(--text-2);margin-left:2px}
.sf-standby__spark{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;height:44px;width:240px;max-width:100%;align-items:end}
.sf-standby__spark i{display:block;height:var(--h);min-height:2px;border-radius:3px 3px 0 0;background:var(--accent);opacity:.85}

/* ---------- Certificate tracking kit (spec 2026-10-10; resources/views/marineIQ/compliance/sf) ----------
   Header glass everywhere (.sf-kpi / .sf-card / .sf-dtable / .sf-menu__panel), compact 32 px controls (.sf-filters). */
.sf-cert-stats{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--space-4)}
@media (max-width:1279px){.sf-cert-stats{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:639px){.sf-cert-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
.sf-cert-stat{appearance:none;font:inherit;color:inherit;margin:0;cursor:pointer;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2);text-align:left}   /* a <button> that keeps the .sf-kpi card */
.sf-cert-stat.is-total{cursor:default}
.sf-cert-stat:focus-visible{box-shadow:var(--focus-ring)}
.sf-cert-stat:not(.is-total):hover::before{background:color-mix(in srgb,var(--glass-fill) 100%,var(--text) 4%)}
.sf-cert-stat.is-active{box-shadow:inset 0 0 0 2px var(--accent)}
.sf-cert-stat .sf-kpi__label{display:inline-flex;align-items:center;gap:var(--space-2)}
.sf-cert-panel{margin-top:var(--space-4)}
.sf-cert-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);padding:var(--space-4) var(--space-4) 0}
.sf-cert-toolbar__end{display:inline-flex;align-items:center;gap:var(--space-2);margin-left:auto}
@media (max-width:639px){.sf-cert-toolbar__end{flex-wrap:wrap;margin-left:0}}   /* phone: the end group sits after the filters and wraps when it must */
/* Phone (owner 2026-10-22: "the buttons are so big in mobile"): buttons keep their desktop size (a 44 px floor made the 32 px filter
   buttons 44), toolbar buttons with a .sf-btn__text label become icons (the name stays in aria-label), and a shortcut tag needs a keyboard */
.sf-sm-only{display:none}
@media (max-width:639px){.sf-sm-only{display:revert}.sf-btn__text{display:none}.sf-btn:has(> .sf-btn__text),.sf-segmented__btn:has(> .sf-btn__text){width:var(--h,32px);padding:0;gap:0;justify-content:center}}
@media (max-width:639px),(hover:none){.sf-btn .sf-kbd{display:none}}
.sf-cert-search{flex:1 1 180px;min-width:160px;max-width:260px}
@media (max-width:639px){.sf-cert-toolbar:has(>[data-dp-side])>.sf-cert-search{flex-basis:120px;min-width:0;max-width:none}}   /* Departments & positions: the side switch shares the search line */
.sf-cert-search input{flex:1;min-width:0;border:0;outline:0;background:transparent;color:var(--text);font:inherit}
.sf-cert-sortpick{display:inline-block;width:170px}
.sf-cert-filters.sf-menu__panel{width:min(560px,calc(100vw - 32px));padding:var(--space-4)}
.sf-cert-filters__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-4)}
@media (max-width:639px){.sf-cert-filters__grid{grid-template-columns:1fr}}
.sf-cert-filters__field{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
.sf-cert-filters__field .sf-segmented{display:flex}
.sf-cert-listbox{padding:var(--space-4)}
.sf-cert-first{display:flex;justify-content:center;padding:var(--space-8) 0}
.sf-cert-listbox.is-loading #assets-list{opacity:.5;transition:opacity var(--dur-fast) var(--ease-standard)}
.sf-cert-two{display:flex;flex-direction:column;gap:2px;min-width:0;line-height:1.3}
.sf-cert-alert{display:inline-flex}.sf-cert-alert.is-error{color:var(--error-text)}.sf-cert-alert.is-warning{color:var(--warning-text)}
.sf-cert-table :is(th,td).sf-cert-table__alert{width:20px;padding-right:0}
.sf-cert-table td{max-width:240px}   /* owner + certificate + 3 dates + 4 actions fit a 1440 screen */
.sf-cert-table .sf-cert-table__actions{width:1%;white-space:nowrap;padding-left:var(--space-2)}
.sf-cert-sort{all:unset;display:inline-flex;align-items:center;gap:2px;cursor:pointer;color:var(--text-2)}
.sf-cert-sort .sf-sort-arrow{visibility:hidden}
th[aria-sort="descending"] .sf-cert-sort .sf-sort-arrow{visibility:visible}
th[aria-sort="ascending"] .sf-cert-sort .sf-sort-arrow{visibility:visible;transform:rotate(180deg)}
.sf-cert-days.is-past{color:var(--error-text)}.sf-cert-days.is-soon{color:var(--warning-text)}
.sf-cert-finding{font:var(--ui-meta);color:var(--accent-text)}
.sf-cert-pager{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding-top:var(--space-4)}   /* legacy name, no longer drawn by the shared pagers */
.sf-cert-pager__nav{display:inline-flex;align-items:center;gap:var(--space-2)}
.sf-cert-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--space-4)}
.sf-cert-card{display:flex;flex-direction:column;gap:var(--space-3)}
.sf-cert-card__head{display:flex;align-items:flex-start;gap:var(--space-3)}
.sf-cert-card__head .sf-cert-two{flex:1}
.sf-cert-card__dates{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3);margin:0}
.sf-cert-card__dates dt{font:var(--ui-meta);color:var(--text-2)}.sf-cert-card__dates dd{margin:0;font:var(--ui-number)}
.sf-cert-card__wide{grid-column:1/-1}.sf-cert-card__dates .sf-cert-card__wide dd{font:var(--ui-body);color:var(--text-2)}
.sf-cert-card__foot{display:flex;align-items:center;gap:var(--space-2);margin-top:auto}
.sf-cert-card__foot .sf-row-actions{margin-left:auto}
.sf-cert-card:is(:hover,:focus-within) .sf-row-actions{opacity:1;pointer-events:auto}
.sf-cert-panel .sf-cert-card{box-shadow:none}
.sf-cert-panel .sf-cert-card::before{background:color-mix(in srgb,var(--glass-fill) 35%,transparent);-webkit-backdrop-filter:none;backdrop-filter:none}   /* card inside the glass panel: lighter tint, no second blur */

/* ---------- List kit (spec 2026-10-11; resources/views/sf/list + compliance-tracking.js as SofonnList) ----------
   Reuses the certificate kit's generic sf-cert-* layout rules; only what a list page adds lives here.
   ponytail: sf-cert-* names shared by both kits; rename to sf-list-* when the certificate kit includes sf/list. */
.sf-list-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:var(--space-4)}
.sf-tabs+.sf-list-stats{margin-top:var(--space-4)}
/* a page's section tabs (vessel Technical / Crewing sub-tabs, 2026-10-19): the same 16 px under them whatever follows */
.sf-main>.sf-tabs{margin-bottom:var(--space-4)}
.sf-main>.sf-tabs+.sf-list-stats{margin-top:0}
/* the section sub-tab row (Technical/_tabs, tracking-asset-crews/_tabs, owner 2026-10-19 "same level as Add new engine"): the tabs
   (+ the page's own switch) left, the page header's buttons right at their own size (TabActions); wraps under the tabs when narrow */
.sf-subtabs{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3)}
.sf-main>.sf-subtabs{margin-bottom:var(--space-4)}
.sf-subtabs>.sf-ph__tab-actions{margin-left:auto}
.sf-subtabs .sf-ph__tab-actions .sf-btn:not(.sf-btn-sm){--h:var(--control-md);--px:16px}
.sf-subtabs .sf-ph__tab-actions :is(.sf-input,.sf-select){height:var(--control-md);font-size:14px}
/* the page header's status line on a tab row (TabActions): a small label before the buttons, one line */
.sf-ph__tab-meta{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--space-1) var(--space-3);font:var(--ui-label);color:var(--text-2)}
/* a status on a tab row = dot + word at the tabs' text size, no pill (owner 2026-10-19: the 22 px badge looked lost beside 40 px controls) */
.sf-ph__tab-meta .sf-badge{height:auto;padding:0;gap:8px;background:none;border:0;font:600 13px/1.2 var(--font-sans)}
.sf-ph__tab-meta .sf-badge:not([class*="is-"]){color:var(--text-2)}
.sf-ph__tab-actions .sf-input:has(> input[data-sf-date]){flex:none;width:180px}   /* a day picker is as wide as a date */
.sf-list-box.is-loading>*{opacity:.5;transition:opacity var(--dur-fast) var(--ease-standard)}
.sf-list-bulkbar{display:flex;align-items:center;gap:var(--space-3);margin:var(--space-3) var(--space-4) 0;padding:var(--space-2) var(--space-3);
    border:1px solid var(--divider);border-radius:var(--radius-md);background:color-mix(in srgb,var(--accent) 8%,transparent)}
.sf-list-bulkbar__actions{display:inline-flex;gap:var(--space-2);margin-left:auto}
.sf-list-tick{gap:0}
.sf-table .sf-list-tickcol{width:1%;padding-right:0}
.sf-table tr:has([data-ct-select]:checked){--sf-row-tint:var(--highlight)}.sf-table tr:has([data-ct-select]:checked) td{background:var(--highlight)}
.sf-list-man{display:inline-flex;align-items:center;gap:var(--space-2)}
.sf-list-man .sf-progress{width:72px}
.sf-list-man.is-short .sf-progress__fill{background:var(--warning-text)}
.sf-manning-alert{margin-top:var(--space-4)}
.sf-manning-chips{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:var(--space-2)}
.sf-manning-req{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent-text)}
/* Rotation (2026-10-19): the crew pair = person · swap glyph · back-to-back (or the Add button), wraps on a narrow column; "Show all" in the alert */
.sf-rot-pair{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-3);min-width:0}
.sf-rot-pair__link{color:var(--text-3);flex:none}
.sf-rot-more{margin-top:var(--space-2)}.sf-rot-more summary{cursor:pointer;font:var(--ui-label);color:var(--accent-text)}
/* print = the page title + the whole table: no app chrome, wallpaper, help button, tabs, toolbar or KPIs; the table unscrolled at full width */
@media print{.sf-header,.sf-sidebar,.sf-breadcrumb,.sf-fleet-scope,.gs-help,.sf-toasts,.sf-cert-toolbar,.sf-tabs,.sf-list-stats,.sf-row-actions,.sf-row-menu,.sf-list-noprint{display:none!important}
  body.sf-app{background:none}body.sf-app::before{display:none}.sf-shell{display:block;padding:0}.sf-main{padding:0}
  .sf-dtable::before,.sf-kpi::before{background:none;backdrop-filter:none}
  .sf-table-wrap{overflow:visible;max-height:none}
  .sf-dtable{overflow:visible;border:0;box-shadow:none;background:none;-webkit-backdrop-filter:none;backdrop-filter:none}.sf-dtable .sf-table-wrap{max-height:none}
  .sf-table.has-sticky-col tbody tr td:first-child,.sf-table.has-sticky-2 tbody tr td:nth-child(2){position:static;background:none}
  .sf-table{width:100%;font-size:11px}.sf-table :is(th,td){position:static;padding:0 var(--space-2);max-width:none;background:none;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}}

/* ---------- Locations (spec 2026-10-12; marineIQ/platform-setup/locations) ---------- */
.sf-loc-tabs{margin-top:var(--space-4)}
/* Departments & positions: the tabs and the On shore | On board switch share one row (the switch is the page's side, in the URL). */
.sf-cert-alerts{margin-bottom:var(--space-4)}.sf-cert-alerts__list{list-style:none;margin:var(--space-2) 0 0;padding:0;display:grid;gap:var(--space-2)}
.sf-cert-alerts__list li{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
/* Operations: a division's name is indented by its depth in the tree (Divisions tab). */
/* Activities / Events: a vessel row's count has its "inherited · custom" line under it; the assignment sheet lists choices in a grid. */
.sf-block{display:block}
.sf-assign-group{display:grid;gap:var(--space-3)}.sf-assign-all{font-weight:600}
.sf-assign-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--space-2) var(--space-4)}
.sf-check.is-locked{opacity:.6}
.sf-ops-name{display:inline-flex;align-items:center;gap:var(--space-2);min-width:0;padding-left:calc(var(--sf-depth,0) * var(--space-5))}
/* A table rendered whole pages on the client (data-sf-page, sofonn.js pagers()): rows of other pages are out of the flow. */
.sf-table tr.sf-page-out{display:none}
.sf-dp-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;margin:var(--space-4) 0}
/* Phone (owner 2026-10-22: "still a lot of empty space"): a page tab bar fills the width, its tabs share it, a bar too long swipes
   (sofonn.js opens it on the selected tab); the profile tab row keeps its own layout */
@media (max-width:639px){.sf-tabs:not(.sf-tabs--underline):not(.sf-ph__nav .sf-tabs){display:flex;width:100%;max-width:100%;overflow-x:auto;scrollbar-width:none}
  .sf-tabs:not(.sf-tabs--underline):not(.sf-ph__nav .sf-tabs)>.sf-tab{flex:1 0 auto;justify-content:center}
  .sf-dp-bar{margin:var(--space-2) 0}}
.sf-loc-name{display:flex;align-items:baseline;gap:var(--space-2);min-width:0}
.sf-loc-name .sf-meta,.sf-loc-name .sf-badge{flex:none}
.sf-loc-sub{display:block}
.sf-loc-tags{display:inline-flex;flex-wrap:wrap;gap:var(--space-1)}
.sf-loc-at{display:inline-flex;flex-direction:column;align-items:flex-end;line-height:1.35}
.sf-loc-dot{display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--ring,var(--accent));margin-right:var(--space-2);vertical-align:middle}
.sf-loc-pos{display:grid;gap:var(--space-3)}
.sf-loc-pos>.sf-segmented{justify-self:start}
.sf-loc-dms{display:flex;align-items:center;gap:var(--space-2)}
.sf-loc-dms>.sf-input:nth-child(1){flex:0 0 76px}
.sf-loc-dms>.sf-input:nth-child(3){flex:0 0 100px}
.sf-loc-hemi{flex:0 0 64px;width:64px}
.sf-loc-unit{color:var(--text-2)}
.sf-loc-range{display:grid;gap:var(--space-3)}
.sf-loc-colour{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.sf-loc-ring{flex:none;width:28px;height:28px;border-radius:50%;border:1.5px dashed var(--ring,var(--accent));background:color-mix(in srgb,var(--ring,var(--accent)) 6%,transparent)}
.sf-loc-ring.is-auto{border-color:var(--border-strong);background:none}
.sf-loc-swatches{display:flex;gap:6px}
.sf-loc-swatch{all:unset;box-sizing:border-box;width:20px;height:20px;border-radius:50%;background:var(--sw);border:1px solid var(--border);cursor:pointer;outline:2px solid transparent;outline-offset:2px;transition:outline-color 80ms linear}
.sf-loc-swatch:hover,.sf-loc-swatch:focus-visible,.sf-loc-swatch.is-active{outline-color:var(--sw)}
.sf-loc-picker{width:28px;height:28px;padding:0;border:0;background:none;cursor:pointer}
.sf-loc-hex{flex:0 0 120px;width:120px}
.sf-loc-hex input{text-transform:uppercase;font-variant-numeric:tabular-nums}
.sf-loc-warn{color:var(--warning-text)}
@media (prefers-reduced-motion:reduce){.sf-loc-swatch{transition:none}}
.sf-loctype-pic{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-4)}
.sf-loctype-crop{width:100%;max-height:320px;overflow:hidden;border-radius:var(--radius-md)}
.sf-loctype-crop img{display:block;max-width:100%}

/* Template editors (restyle 2026-10-12): one card of fields (name · responsible · type…), then the React table card (.sf-bs) with its loading bar. */
.sf-tpl-panel{margin-bottom:var(--space-4)}
.sf-tpl-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--space-4)}
.sf-tpl-progress{width:100%}
.sf-tpl-progress .sf-progress__fill{font-size:0}
/* Template editor lines (owner Chrome test 2026-10-19: "not user friendly to see and read"): the React table is a .sf-table that fits
   1024–1440 px without sideways scroll — the certificate column takes the room (full name in a wide select, tooltip; category as a small
   tag-select under it), the switch columns stay narrow with wrapping sentence-case headers, Warn before is a number of days. The header
   sticks under the app header while the page scrolls (the card does not scroll on its own); below 768 px a line wraps into a card. */
.sf-tpl-tablehead{display:flex;align-items:center;gap:var(--space-1);margin-bottom:var(--space-3)}
.sf-tpl-tablehead__t{margin:0;font:var(--ui-card-title);color:var(--text)}
.sf-app .sf-tpl-editor .sf-bs .table-responsive{overflow:visible}
.sf-tpl-table{table-layout:fixed}
.sf-tpl-table th{top:calc(var(--space-4) + 52px);z-index:3;white-space:normal;vertical-align:bottom;padding:var(--space-2) var(--space-3);line-height:1.25}
.sf-tpl-table td{max-width:none;padding:var(--space-2) var(--space-3);height:56px}
.sf-tpl-table tr.bg-light-danger>td{background:var(--error-tint)}   /* a certificate picked twice (the save script marks the lines) */
.sf-tpl-table .sf-tpl-pos{width:20%}
.sf-tpl-table .sf-tpl-sw{width:96px;text-align:center}
.sf-tpl-table .sf-tpl-warn{width:144px}
.sf-tpl-table .sf-tpl-exp{width:184px}
.sf-tpl-table .sf-tpl-act{width:48px;text-align:right}
.sf-tpl-select{display:block;width:100%;min-width:0;height:var(--control-sm);padding:0 var(--space-2);border-radius:var(--radius-sm);border:1px solid var(--glass-border);
  background:color-mix(in srgb,var(--field) 55%,transparent);color:var(--text);font:500 13px/1.2 var(--font-sans);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
.sf-tpl-cat{display:inline-block;max-width:100%;height:22px;margin-top:var(--space-1);padding:0 var(--space-2);border-radius:var(--radius-pill);border:1px solid var(--border);
  background:var(--surface-2);color:var(--text-2);font:var(--ui-meta);font-weight:600;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;cursor:pointer}
:is(.sf-tpl-select,.sf-tpl-cat,.sf-tpl-days input,.sf-tpl-days select):hover{border-color:var(--border-strong)}
:is(.sf-tpl-select,.sf-tpl-cat,.sf-tpl-days input,.sf-tpl-days select):focus-visible{outline:none;border-color:var(--accent);box-shadow:var(--focus-ring)}
.sf-tpl-sw .sf-switch{vertical-align:middle}
.sf-tpl-days{display:inline-flex;align-items:center;gap:var(--space-1);font:var(--ui-meta);color:var(--text-2)}
.sf-tpl-days input,.sf-tpl-days select{height:var(--control-sm);padding:0 var(--space-2);border-radius:var(--radius-sm);border:1px solid var(--glass-border);
  background:color-mix(in srgb,var(--field) 55%,transparent);color:var(--text);font:var(--ui-number);font-variant-numeric:tabular-nums}
.sf-tpl-days input{width:84px;text-align:right}
.sf-tpl-dash{color:var(--text-3)}
.sf-tpl-add{margin-top:var(--space-3)}
.sf-tpl-editor .sf-btn .spinner-border{display:inline-block;width:14px;height:14px;border-radius:50%;border:2px solid currentColor;border-right-color:transparent;animation:sf-spin .8s linear infinite}   /* $.easyAjax "Loading..." on Save while the save runs */
@media (hover:none){.sf-tpl-table .sf-row-actions{opacity:1}}   /* touch: no hover to reveal the one trash */
@media (max-width:767px){
  .sf-tpl-table,.sf-tpl-table tbody{display:block;table-layout:auto}
  .sf-tpl-table thead{display:none}
  .sf-tpl-table tr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-4);padding:var(--space-3) 0;border-bottom:1px solid var(--divider)}
  .sf-tpl-table td{display:block;width:auto;height:auto;padding:0;border:0}
  .sf-tpl-table :is(.sf-tpl-warn,.sf-tpl-exp){width:auto}   /* the desktop column widths are narrower than "Experience 90 days" */
  .sf-tpl-cat{height:28px}   /* the category tag-select is tapped here */
  .sf-tpl-table :is(.sf-tpl-cert,.sf-tpl-pos){flex:1 1 100%}
  .sf-tpl-table td[data-label]{display:flex;align-items:center;gap:var(--space-2)}
  .sf-tpl-table td[data-label]::before{content:attr(data-label);font:var(--ui-label);color:var(--text-2)}
  .sf-tpl-table .sf-tpl-act{margin-left:auto}
}
/* Photo card (Tank reports landing, 2026-10-13): <x-sf.photo-card> = a flush .sf-card (same glass layer) with the record's picture
   on top at 2:1, a dimmed tint in dark mode, and a body; as a link the card is one focusable target, hover = border one step stronger. */
.sf-photo-card{display:flex;flex-direction:column;color:var(--text);text-decoration:none;transition:border-color var(--dur-hover) linear}
a.sf-photo-card:hover{color:var(--text);border-color:var(--border-strong)}
a.sf-photo-card:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.sf-photo-card__img{display:block;width:100%;aspect-ratio:2/1;object-fit:cover;background:var(--surface-2)}
.sf-photo-card__img.is-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-1);font:600 11px/1 var(--font-sans);color:var(--text-3)}
img.sf-photo-card__img{filter:var(--photo-dim)}   /* dark mode dims photos (token --photo-dim) */
.sf-photo-card__body{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3) var(--space-4) var(--space-4);min-width:0}
.sf-photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,260px),1fr));gap:var(--space-4)}
/* Spark line (Tank reports, 2026-10-13): a plain inline SVG trend, accent line + soft fill, no axes; the empty state is a dashed box. */
.sf-spark{display:block;width:100%;height:34px}
.sf-spark .a{fill:var(--accent);fill-opacity:.12;stroke:none}
.sf-spark .l{fill:none;stroke:var(--accent);stroke-width:1.8;vector-effect:non-scaling-stroke}
.sf-spark.is-empty{display:grid;place-items:center;font-size:11px;color:var(--text-3);border:1px dashed var(--divider);border-radius:var(--radius-sm)}
/* Export (<x-sf.export>, 2026-10-13): the format list reads on one line per item */
.sf-export .sf-menu__panel{min-width:220px}
.sf-export .sf-menu__item{white-space:nowrap}
.sf-dtable__tools>.sf-export{margin-left:auto}   /* Export = the right end of a table's toolbar (owner 2026-10-13), even alone */

/* Header once scrolled (option A, owner 2026-10-13; at rest the header is unchanged): 52 px, Fleet / Quick Actions folded to
   their icon, the account to the photo; the sidebar follows the shorter header (body.sf-scrolled, set by sofonn.js — a body
   class, never a :has() rule on chrome) so the gap stays 16 px and the sidebar grows 12 px. */
.sf-sidebar{transition:top var(--dur-base) var(--ease-standard),height var(--dur-base) var(--ease-standard),width var(--dur-base) var(--ease-standard)}
.sf-scrolled .sf-sidebar{--sf-side-top:calc(var(--space-4) + 52px + var(--space-4))}
.sf-header .fs-trigger,.sf-header .sf-qa__trigger{transition:width var(--dur-base) var(--ease-standard),padding var(--dur-base) var(--ease-standard)}
.sf-header.is-compact :is(.fs-trigger,.sf-qa__trigger){width:32px;padding:0;justify-content:center}
.sf-header.is-compact :is(.fs-trigger,.sf-qa__trigger) :is(.sf-hide-sm,.fs-ico-sm){display:none}
.sf-header.is-compact .sf-account__name{display:none}
.sf-header.is-compact .sf-account__trigger{padding:4px}
@media (prefers-reduced-motion:reduce){.sf-sidebar,.sf-header .fs-trigger,.sf-header .sf-qa__trigger{transition:none}}
/* Quick Actions (on-board header): the Fleet trigger's shape, the header glass menu */
.sf-header .sf-qa__trigger{--h:32px;--px:12px;gap:8px;border-radius:var(--radius-pill);background:var(--glass-fill);border-color:var(--glass-border);font:700 13px/1 var(--font-sans);color:var(--text)}
.sf-header .sf-qa__trigger:hover{background:var(--surface-2)}
.sf-qa__panel{width:320px;max-width:calc(100vw - 24px);padding:var(--space-2)}
.sf-qa__head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-3) var(--space-3);margin-bottom:var(--space-1);border-bottom:1px solid var(--divider)}
.sf-qa__head p{margin:0}
.sf-qa__row{justify-content:space-between}
.sf-qa__row.is-soon{color:var(--text-3);cursor:default}
.sf-qa__ok{color:var(--success)}

/* Crew tasks (on-board header, 2026-10-13 — the old header's pending events + positions to fix; <x-sf.crew-tasks>) */
@media (min-width:640px){.sf-account__name{display:flex;flex-direction:column;line-height:1.2}}   /* phones keep .sf-hide-sm */
.sf-account__vessel{font:var(--ui-meta);color:var(--text-2)}
.sf-crew__panel{width:380px;max-width:calc(100vw - 24px);padding:var(--space-2)}
.sf-crew__list{max-height:360px;overflow-y:auto;overscroll-behavior:contain}
.sf-crew__row{position:relative;display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md)}
.sf-crew__row:hover{background:var(--surface-2)}
.sf-crew__dot{flex:0 0 10px;width:10px;height:10px;margin-top:4px;border-radius:50%;background:var(--dot,var(--text-3))}
.sf-crew__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;font:var(--ui-label);color:var(--text);text-decoration:none}
.sf-crew__text .sf-badge{align-self:flex-start;margin-top:4px}
a.sf-crew__text:hover b{color:var(--accent-text)}
.sf-crew__ignore{color:var(--text-3);opacity:0;transition:opacity var(--dur-hover) var(--ease-standard)}
.sf-crew__row:is(:hover,:focus-within) .sf-crew__ignore{opacity:1}
@media (hover:none){.sf-crew__ignore{opacity:1}}
.sf-crew__pos{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-2) var(--space-3)}
.sf-crew__pos+.sf-crew__pos{border-top:1px solid var(--divider)}
.sf-crew__pos .sf-label{margin:0}
.sf-crew__fields{display:grid;grid-template-columns:1fr 1fr auto;gap:var(--space-2);align-items:center}
.sf-crew__demo{margin-left:0;justify-content:flex-start}
.sf-crew__text{padding:2px 6px;margin:-2px -6px;border-radius:var(--radius-sm)}
.sf-crew__text:focus-visible{outline:0;box-shadow:var(--focus-ring)}
.sf-crew__fields>*{min-width:0}

/* Vessel card (master dashboard, <x-vessel-hero skin="sf">, 2026-10-13): the ship stage + the four figures as x-sf.kpi */
.sf-vessel-card__body{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--space-4);align-items:stretch}
.sf-vessel-card__visual{min-width:0;border-radius:var(--radius-lg);overflow:hidden}
.sf-vessel-card__visual .vh-ship3d canvas{border-radius:var(--radius-lg)}
.sf-vessel-card__kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-3);align-content:start}
.sf-vessel-card__kpi{padding:var(--space-4)}
@media (max-width:767px){.sf-vessel-card__body{grid-template-columns:minmax(0,1fr)}}
/* the master minimap in a glass card (_master-minimap, skin 'sf'): its caption + hint on the design system's tokens */
.md-minimap.sf-card{display:flex;flex-direction:column;min-height:280px;height:100%}
.md-minimap.sf-card .md-minimap__map{background:var(--surface)}
.md-minimap.sf-card .md-minimap__cap{background:transparent;border-top:1px solid var(--divider);color:var(--text-2);font:var(--ui-meta)}
.md-minimap.sf-card .md-minimap__cap b{color:var(--text);font:var(--ui-label)}
.md-minimap.sf-card .md-minimap__hint{background:var(--glass-fill);border-color:var(--glass-border);color:var(--text);font:var(--ui-meta)}
.md-minimap.sf-card .md-minimap__src.is-live::before{background:var(--success)}

/* ---------- Facts: label / value rows (<dl class="sf-facts"> + x-sf.fact), vessel Details 2026-10-13 ---------- */
.sf-facts{display:flex;flex-direction:column;margin:0}
.sf-fact{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-4);padding:var(--space-3) 0;border-top:1px solid var(--divider)}
.sf-fact:first-child{border-top:0;padding-top:0}
.sf-fact:last-child{padding-bottom:0}
.sf-fact dt{font:var(--ui-label);color:var(--text-2);flex:none}
.sf-fact dd{margin:0;min-width:0;text-align:right;color:var(--text);overflow-wrap:anywhere}
.sf-fact dd.is-empty{color:var(--text-3)}
@media (max-width:639px){.sf-fact{flex-wrap:wrap;row-gap:var(--space-1)}.sf-fact dd{margin-left:auto}}   /* phone: a value too long for the line goes under its label */
.sf-card__actions>.sf-btn-icon.sf-btn-sm:only-child{margin-block:-6px}   /* a lone small icon button never makes a card head taller than its title (cards in a row stay aligned) */
.sf-table td .sf-switch-row{justify-content:flex-start;padding:0;border-top:0}   /* a switch in a cell sits under its column (Best practice alerts) */

/* ---------- Map box: a map inside a flush glass card (vessel Overview, 2026-10-13); its loading / retry state is centred ---------- */
.sf-map-box{height:min(70vh,560px);min-height:320px;border-top:1px solid var(--divider);margin-top:var(--space-4)}
.sf-map-box__state{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3)}

/* ---------- Daily report day pages (owner 2026-10-14): the day navigator in the page header + the day approval bar ---------- */
.sf-daynav{display:inline-flex;align-items:center;gap:var(--space-1)}
.sf-daynav__field .sf-input{width:168px}
.sf-daynav .sf-btn-icon:disabled{opacity:.38;cursor:not-allowed}
.sf-daybar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-3) var(--space-4);margin-bottom:var(--space-4)}
.sf-daybar__sections{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3);min-width:0}
.sf-daybar__tab .sf-icon{flex:none}
.sf-daybar__tab.is-done:not(.is-selected) .sf-icon{color:var(--success)}
.sf-daybar__tab.is-blocked:not(.is-selected) .sf-icon{color:var(--warning)}
.sf-daybar__tab.is-selected .sf-dot{background:currentColor}
.sf-daybar__tab.is-soon:not(.is-selected){opacity:.5;cursor:default}
.sf-daybar__actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin-left:auto}
.sf-daybar__actions .sf-segmented{height:var(--control-sm);padding:2px}
.sf-daybar__actions .sf-segmented__btn{height:26px;padding:0 10px}
/* Phone (owner 2026-10-22, Time sheet): the section tabs take the first line, the approval line and the List | Calendar switch share the next
   (the switch had a line of its own) */
@media (max-width:639px){.sf-daybar{display:grid;grid-template-columns:minmax(0,1fr) auto;row-gap:var(--space-2)}.sf-daybar__sections{display:contents}
  .sf-daybar__sections>.sf-tabs{grid-column:1/-1}.sf-daybar__actions{margin-left:0}}
.sf-daybar__hint{position:absolute;top:calc(100% + 8px);right:0;z-index:61;white-space:nowrap;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);
  background:var(--surface-elevated);border:1px solid var(--accent);font:var(--ui-meta);color:var(--text)}
.sf-facts.is-compact{margin-top:var(--space-2)}   /* label / value rows revealed inside a table cell (Timesheet "Show more") */
.sf-facts.is-compact .sf-fact{padding:var(--space-1) 0;font:var(--ui-meta)}
.sf-facts.is-compact .sf-fact dt{font:var(--ui-meta);font-weight:600}
.sf-link-btn{all:unset;box-sizing:border-box;display:inline-block;margin-top:2px;cursor:pointer;font:var(--ui-meta);font-weight:600;color:var(--accent-text)}   /* a text button that reads as a link (Show more) */
.sf-link-btn:hover{text-decoration:underline}
.sf-link-btn:focus-visible{border-radius:var(--radius-xs);box-shadow:var(--focus-ring)}
.sf-table td .sf-link-btn{margin-top:0;font:inherit}   /* a link button in a cell (a count that opens its detail) reads like the cell's links */
.sf-table tr.is-flagged>td{background:var(--warning-tint)}   /* a row that needs a look (a conflict's differing field), with its badge — never a red outline */
.sf-swatch{flex:none;display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--c,var(--text-3));box-shadow:inset 0 0 0 1px var(--divider)}   /* a record's own colour (a product on charts), never tinted (owner 2026-10-15) */
.swal2-html-container .sf-swal-choice{display:grid;gap:var(--space-2);text-align:left}   /* radio choices inside a SweetAlert confirm (delete an activity: keep / close the time) */
.swal2-html-container .sf-swal-choice p{margin:0}
/* an alert that lists items, each with its one neutral action (Timesheet day alerts, GPS cross-check — 2026-10-14) */
.sf-alert__body{flex:1 1 auto;min-width:0}
.sf-alert__list{list-style:none;margin:var(--space-2) 0 0;padding:0}
.sf-alert__list li{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0;border-top:1px solid var(--divider);font-variant-numeric:tabular-nums}
.sf-alert__list li:first-child{border-top:0}
.sf-alert__list li>span:not(.sf-avatar){flex:1 1 auto;min-width:0}
.sf-alert__fold>summary{cursor:pointer;font:var(--ui-label);color:var(--text)}
.sf-day-alert{margin-bottom:var(--space-3)}
.sf-table td.is-num .sf-input{width:150px;height:var(--control-sm);margin-left:auto}   /* a figure typed in a table cell (ROB "Enter today") */
.sf-table td.is-num .sf-input input{text-align:right}
/* a record's comments in a menu panel: the list + a field to add one (ROB tank card, 2026-10-14) */
.sf-comments__panel{width:min(380px,calc(100vw - 32px));padding:var(--space-3)}
.sf-comments__list{list-style:none;margin:0;padding:0;max-height:320px;overflow-y:auto}
.sf-comments__list li{display:flex;gap:var(--space-2);padding:var(--space-2) 0;border-top:1px solid var(--divider)}
.sf-comments__list li:first-child{border-top:0}
.sf-comments__list .sf-body{margin:2px 0 0;overflow-wrap:anywhere}
.sf-comments__who{margin:0;font:var(--ui-label)}
.sf-comments__form{display:flex;align-items:flex-end;gap:var(--space-2);margin-top:var(--space-2)}
.sf-comments__form .sf-textarea{flex:1 1 auto}
.sf-comments__form textarea{min-height:56px;padding-bottom:10px}
/* Fleet Monitoring landing (fleet/landing, merged from origin/main 2026-10-14): Cards | Table switch */
.sf-fleet-landing[data-fl-view="cards"] .fl-as-table,.sf-fleet-landing[data-fl-view="table"] .fl-as-cards{display:none}
/* its division chips (a segmented switch up to 5, else a wrapping row of neutral chips) and the page's main count large (2026-11-02) */
.sf-fleet-landing .fl-divisions{display:flex;width:fit-content;max-width:100%;margin-bottom:var(--space-4)}
.sf-fleet-landing .fl-divisions .sf-segmented__btn{text-decoration:none}
.sf-fleet-landing .fl-chips{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-bottom:var(--space-4)}
.sf-fleet-landing .fl-chip-n{font-variant-numeric:tabular-nums;opacity:.6}
.sf-fleet-landing .fl-count{display:flex;flex-direction:column;gap:2px;margin:0}
.sf-fleet-landing .fl-count b{font:var(--ui-kpi);letter-spacing:var(--track-kpi);font-variant-numeric:tabular-nums;color:var(--text)}
.sf-fleet-landing .fl-count span{font:var(--ui-meta);color:var(--text-2)}
@media (max-width:639px){.sf-fleet-landing .fl-divisions{display:flex;flex-wrap:wrap;height:auto;border-radius:var(--radius-lg)}}
/* Update current location pop-up (layout B "map first", owner 2026-10-14): the position form | the map + last trips.
   update-location.blade.php + sofonn-location-sheet.js; the list = .sf-voyage (ajax/asset-locations-log). */
.sf-locsheet{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:var(--space-6);padding:var(--space-2) 0}
.sf-locsheet__col{display:flex;flex-direction:column;gap:var(--space-3);min-width:0}
.sf-locsheet__t{display:flex;align-items:center;gap:var(--space-2);margin:var(--space-1) 0 0;font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-3)}
.sf-locsheet__t::after{content:"";flex:1;height:1px;background:var(--divider)}
.sf-locsheet__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
.sf-locsheet__head .sf-locsheet__t{flex:1;margin:0}
.sf-locsheet__pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-3)}
.sf-locsheet__trio{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-3)}
.sf-locsheet__mar{margin:calc(-1 * var(--space-1)) 0 0;font:var(--ui-meta);color:var(--text-2);font-variant-numeric:tabular-nums}
.sf-locsheet__mar b{font-weight:700;color:var(--text)}
.sf-locsheet__map{position:relative;isolation:isolate;aspect-ratio:4/3;max-width:100%;border:1px solid var(--divider);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-2)}
.sf-locsheet__map .leaflet-container,.sf-locsheet__map.leaflet-container{background:var(--surface-2);font:var(--ui-meta)}
.sf-locsheet__map.is-pick.leaflet-container{cursor:crosshair}
/* the two labels on the map = the shared .map-glass (map-liquid-glass.css), placed here */
.sf-locsheet__cap.map-glass,.sf-locsheet__tip.map-glass{position:absolute;z-index:1000;display:inline-flex;align-items:center;height:26px;padding:0 10px;border-radius:var(--radius-pill);font:600 11.5px/1 var(--font-sans);color:var(--text-2);font-variant-numeric:tabular-nums;pointer-events:none}
.sf-locsheet__cap{left:10px;bottom:10px}
.sf-locsheet__tip{right:10px;top:10px}
.sf-locsheet__list{max-height:420px;overflow-y:auto}
@media (max-width:860px){.sf-locsheet{grid-template-columns:minmax(0,1fr)}}
@media (max-width:480px){.sf-locsheet__trio{grid-template-columns:minmax(0,1fr)}}
/* A vessel's voyage history: one hairline list, newest first — a journey (origin → destination · times · its fixes) or a position */
.sf-voyage{list-style:none;margin:0;padding:0;border:1px solid var(--divider);border-radius:var(--radius-lg)}
.sf-voyage__item{display:grid;grid-template-columns:14px minmax(0,1fr) auto;gap:2px var(--space-3);align-items:baseline;padding:10px 14px;border-top:1px solid var(--divider);transition:background var(--dur-hover) var(--ease-standard)}
.sf-voyage__item:first-child{border-top:0}
.sf-voyage__item:hover{background:color-mix(in srgb,var(--text) 4%,transparent)}
.sf-voyage__dot{width:9px;height:9px;border-radius:50%;border:2px solid var(--accent);background:var(--bg-raised);align-self:center}
.sf-voyage__item.is-in_transit .sf-voyage__dot,.sf-voyage__item.is-departed .sf-voyage__dot{border-color:var(--warning-text)}
.sf-voyage__item.is-fix .sf-voyage__dot{border-color:var(--text-3)}
.sf-voyage__route{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:600 13px/1.35 var(--font-sans);color:var(--text)}
.sf-voyage__route span{padding:0 6px;color:var(--text-3)}
.sf-voyage__when{font:600 12px/1.35 var(--font-sans);color:var(--text-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.sf-voyage__sub{grid-column:2/4;margin:0;font:var(--ui-meta);color:var(--text-3);font-variant-numeric:tabular-nums}
.sf-voyage__fixes{grid-column:2/4;display:flex;flex-direction:column;gap:2px;margin:6px 0 0;padding:0 0 0 10px;list-style:none;border-left:1px dashed var(--border-strong);font:var(--ui-meta);color:var(--text-2);font-variant-numeric:tabular-nums}
.sf-voyage__fixes li{display:flex;justify-content:space-between;gap:var(--space-3)}
.sf-voyage__fixes b{font-weight:600;color:var(--text-2);white-space:nowrap}
.sf-locsheet__map.leaflet-container:focus:not(:focus-visible){outline:none}
.sf-locsheet__map.leaflet-container:focus-visible{outline:none;box-shadow:var(--focus-ring)}

/* a fieldset used only to disable a group of fields at once (employee self-lock): no box of its own */
.sf-fieldset{border:0;margin:0;padding:0;min-width:0}
/* Section label row inside a table body (<tr class="sf-table__group">): a quiet label, not a data row — no sticky, no hover tint. */
.sf-table tr.sf-table__group :is(th,td){position:static;height:32px;padding:0 var(--space-4);background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;font:var(--ui-label);color:var(--text-2);text-align:left}
.sf-table tbody tr.sf-table__group:hover td{background:var(--surface)}
.sf-table tr.sf-table__group td:has(> .sf-row-actions){text-align:right}

/* ---------- Technical › ROB (marineIQ/technical/admin-rob-product, 2026-10-15) ---------- */
/* a closing figure the day's movements do not explain: warning icon + the gap before it; fill = bar (limit tick) + percent */
.sf-rp-gap{display:inline-flex;align-items:center;gap:4px;margin-right:var(--space-2);font:var(--ui-label);color:var(--warning-text)}
.sf-rp-fill{display:inline-flex;align-items:center;justify-content:flex-end;gap:var(--space-2)}
.sf-rp-fill .sf-progress{width:76px}
.sf-rp-pct{min-width:3.5ch;font-weight:600}
.sf-rp-pct.is-over{color:var(--error-text)}

/* ---------- Org chart (x-sf.org-chart + sofonn-org-chart.js; Divisions › Chart, owner 2026-10-16 option A) ----------
   One flush glass card: a compact bar (search, zoom, Fit, Fold all), the stage (boxes over SVG elbows, scrolls inside) | the details
   panel. Boxes = nested surface (lighter tint, no second blur); the picked box and its path = accent; a match = warning ring; the rest
   dims while searching; a drop target = dashed accent. */
.sf-org{display:flex;flex-direction:column}
.sf-org__bar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--divider)}
.sf-org__search{height:var(--control-sm);padding:0 12px;flex:0 1 260px;min-width:0}
.sf-org__search input{all:unset;flex:1;min-width:0;font:400 13px/1 var(--font-sans);color:var(--text)}
.sf-org__search input::placeholder{color:var(--text-3)}
.sf-org__spacer{flex:1}
.sf-org__zoom{min-width:44px;text-align:center;font:var(--ui-meta);font-variant-numeric:tabular-nums;color:var(--text-2)}
.sf-org__body{display:grid;grid-template-columns:minmax(0,1fr) 300px;min-height:480px}
.sf-org__stage{position:relative;min-width:0;overflow:auto;max-height:min(70vh,720px)}
.sf-org__sizer{position:relative}
.sf-org__plane{position:absolute;transform-origin:0 0}
.sf-org__edges{position:absolute;inset:0;overflow:visible;pointer-events:none}
.sf-org__edges path{fill:none;stroke:var(--border-strong);stroke-width:1.5}
.sf-org__edges path.is-on{stroke:var(--accent);stroke-width:2}
.sf-org__node{position:absolute;display:flex;flex-direction:column;justify-content:center;gap:4px;padding:10px 12px;border-radius:var(--radius-lg);
  background:color-mix(in srgb,var(--surface-elevated) 72%,transparent);border:1px solid var(--border);color:var(--text);cursor:pointer;user-select:none;
  transition:border-color var(--dur-hover) var(--ease-standard),background var(--dur-hover) var(--ease-standard),opacity var(--dur-fast) linear}
.sf-org__node:hover{border-color:var(--border-strong)}
.sf-org__node:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.sf-org__node.is-sel{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,var(--surface-elevated));box-shadow:0 0 0 3px var(--highlight)}
.sf-org__node.is-path{border-color:color-mix(in srgb,var(--accent) 55%,var(--border))}
.sf-org__node.is-dim{opacity:.38}
.sf-org__node.is-match{box-shadow:0 0 0 2px var(--warning)}
.sf-org__node.is-drop{border-color:var(--accent);border-style:dashed;background:var(--highlight)}
.sf-org__node.is-root{background:var(--surface-2);border-style:dashed;cursor:default}
.sf-org__top{display:flex;align-items:center;gap:var(--space-2);min-width:0}
.sf-org__chip{flex:none;font:700 11px/1 var(--font-sans);letter-spacing:.03em;padding:4px 6px;border-radius:6px;background:var(--surface-2);color:var(--text-2)}
.sf-org__node.is-sel .sf-org__chip{background:var(--accent);color:var(--text-on-accent)}
.sf-org__name{min-width:0;font:600 13px/1.3 var(--font-sans);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-org__meta{display:flex;gap:10px;font:var(--ui-meta);color:var(--text-2);font-variant-numeric:tabular-nums}
.sf-org__meta b{color:var(--text);font-weight:700}
.sf-org__tog{all:unset;box-sizing:border-box;position:absolute;left:50%;bottom:-11px;transform:translateX(-50%);display:grid;place-items:center;min-width:22px;height:22px;padding:0 5px;
  border-radius:var(--radius-pill);background:var(--surface-elevated);border:1px solid var(--border);font:700 11px/1 var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text-2);cursor:pointer}
.sf-org__tog:hover{color:var(--text);border-color:var(--accent)}
.sf-org__tog:focus-visible{box-shadow:var(--focus-ring)}
.sf-org__panel{border-left:1px solid var(--divider);padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-4);min-width:0}
.sf-org__pick,.sf-org__none{margin:0;color:var(--text-3)}
.sf-org__crumbs{margin:0;font:var(--ui-meta);color:var(--text-3)}
.sf-org__title{margin:0;display:flex;align-items:center;gap:var(--space-2);font:700 16px/1.3 var(--font-sans);color:var(--text);text-wrap:balance}
.sf-org__facts{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2);margin:0}
.sf-org__facts div{padding:10px 12px;border-radius:var(--radius-md);background:var(--surface-2)}
.sf-org__facts dt{font:var(--ui-meta);color:var(--text-2)}
.sf-org__facts dd{margin:0;font:var(--ui-stat);font-variant-numeric:tabular-nums;color:var(--text)}
.sf-org__h{margin:0 0 6px;font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-3)}
.sf-org__tags{display:flex;flex-wrap:wrap;gap:6px}
.sf-org__tag{padding:4px 8px;border-radius:var(--radius-pill);border:1px solid var(--border);font:var(--ui-label);font-weight:500;color:var(--text-2)}
.sf-org__subs{display:flex;flex-direction:column;gap:2px}
.sf-org__subs button{all:unset;box-sizing:border-box;cursor:pointer;display:flex;justify-content:space-between;gap:var(--space-2);padding:6px 8px;border-radius:var(--radius-sm);font:var(--ui-body);color:var(--text)}
.sf-org__subs button:hover{background:var(--surface-2)}
.sf-org__subs button:focus-visible{box-shadow:var(--focus-ring)}
.sf-org__n{font-variant-numeric:tabular-nums;color:var(--text-2)}
.sf-org__acts{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:auto}
.sf-org__hint{margin:0;padding:var(--space-2) var(--space-4);border-top:1px solid var(--divider);font:var(--ui-meta);color:var(--text-3)}
@media (max-width:1023px){.sf-org__body{grid-template-columns:minmax(0,1fr)}.sf-org__panel{border-left:0;border-top:1px solid var(--divider)}}
@media (max-width:639px){.sf-org__search{flex:1 1 100%}}
@media (prefers-reduced-motion:reduce){.sf-org__node{transition:none}}
/* a toast with an action (the org chart's Undo): text and button on one line */
.sf-toast:has(.sf-toast__undo){display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
/* Status page (layout/sofonn-status, 2026-10-16): the error pages and "No vessel assigned" = one glass card centred on the app
   background; logo, icon tile, code, title, text, one primary. */
.sf-statuspage{min-height:100vh;display:grid;place-items:center;padding:var(--space-6) var(--space-4)}
.sf-statuspage__card{width:min(480px,100%);display:flex;flex-direction:column;align-items:center;gap:var(--space-3);padding:var(--space-10) var(--space-6);text-align:center}
.sf-statuspage__logo{height:24px;width:auto;margin-bottom:var(--space-4)}
.sf-statuspage__code{margin:var(--space-2) 0 0;font:600 12px/1 var(--font-sans);letter-spacing:.08em;text-transform:uppercase;color:var(--accent-text)}
.sf-statuspage__title{margin:0;font:700 24px/1.25 var(--font-sans);color:var(--text)}
.sf-statuspage__text{margin:0 0 var(--space-3);max-width:36ch;color:var(--text-2)}

/* Locations tree (spec 2026-10-17 §5.5): indent by depth, a chevron that turns when the branch is open */
.sf-tree-bar{display:flex;gap:8px;margin:0 0 8px}
.sf-table td.sf-tree-name{padding-inline-start:calc(12px + var(--depth,0) * 20px);white-space:nowrap}
.sf-tree-name .sf-loc-name{display:inline-flex;vertical-align:middle;max-width:calc(100% - 26px);overflow:hidden}
.sf-loc-name>.sf-truncate{min-width:0}   /* the name ends in … inside its cell instead of running over the next column */
@media (max-width:639px){.sf-tree-name .sf-loc-name>:is(.sf-meta,.sf-badge){display:none}}   /* phone: the pinned name is a third of the screen, the name alone */
.sf-table td.sf-tree-name>.sf-truncate{display:inline-block;vertical-align:middle;max-width:calc(100% - 26px)}
.sf-tree-toggle,.sf-tree-gap{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-inline-end:4px;vertical-align:middle}
.sf-tree-toggle{border:0;background:transparent;color:var(--text-2);border-radius:var(--radius-sm,6px);cursor:pointer;padding:0}
.sf-tree-toggle:hover{background:var(--surface-2,rgba(128,128,128,.12))}
.sf-tree-toggle .sf-icon{transition:transform 120ms ease}
.sf-tree-toggle[aria-expanded="true"] .sf-icon{transform:rotate(90deg)}
tr.sf-tree-branch{font-weight:500}
tr[data-tree-hidden]{display:none}
.sf-alert__line{display:block}
.sf-alert__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.sf-pos{display:inline-flex;flex-direction:column;gap:2px}
.sf-area-block{border:0;margin:0;padding:0;min-width:0}
.sf-area-choice{display:flex;flex-wrap:wrap;gap:16px;margin-bottom:12px}

/* ⓘ note: the icon inline, opens a small panel under it (rule control spec 2026-10-19 §10) */
.sf-info { position: relative; display: inline-block; vertical-align: middle; }
.sf-info > summary { list-style: none; cursor: pointer; color: var(--text-2); line-height: 0; padding: var(--space-1); border-radius: var(--radius-sm); transition: color var(--dur-hover) var(--ease-standard), background var(--dur-hover) var(--ease-standard); }
.sf-info > summary::-webkit-details-marker { display: none; }
.sf-info > summary:hover { color: var(--text); background: var(--surface-2); }
.sf-info > summary:focus-visible { color: var(--text); outline: none; box-shadow: var(--focus-ring); }
.sf-info[open] > summary { color: var(--accent-text); }
/* owner 2026-10-19: opening never moves the icon or pushes the page — the note floats under it, solid (surface-elevated), in front of everything, inside the screen, every line wraps */
.sf-info dl { position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; width: max-content; max-width: min(560px, calc(100vw - 32px)); margin: 0; padding: var(--space-3); border-radius: var(--radius-md); background: var(--surface-elevated); border: 1px solid var(--glass-border); box-shadow: var(--shadow-e3); display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-3); font: var(--ui-body); text-transform: none; letter-spacing: normal; text-align: left; }   /* a note inside an upper-case heading (tank screen) reads normally */
.sf-info dt { font: var(--ui-label); color: var(--text-2); }
.sf-info dd { margin: 0; color: var(--text); overflow-wrap: anywhere; }
.sf-info.is-end dl { left: auto; right: 0; }   /* near the right edge: the note opens leftwards (sofonn.js) */
.sf-info dl[popover] { position: fixed; right: auto; bottom: auto; overflow: visible; }   /* a column's ⓘ (x-sf.th info): lifted to the top layer by sofonn.js, top / left set there */
.sf-table th .sf-info > summary { margin-block: calc(-1 * var(--space-1)); }   /* the ⓘ keeps the header row one label high */
:is(.sf-ph,.sf-card,.sf-kpi,.sf-dtable):has(.sf-info[open]){z-index:70}   /* the open note paints over the cards below, as an open menu does; never on chrome */
@media (max-width: 480px) { .sf-info dl { grid-template-columns: 1fr; gap: var(--space-1); } .sf-info dd { margin-bottom: var(--space-2); } }
/* Code input (x-sf.code-input, 2026-10-20): one field-shaped box per digit, 3 + 3 */
.sf-code{display:flex;justify-content:center;gap:var(--space-2)}
.sf-code__box{width:44px;height:52px;padding:0;text-align:center;font:700 22px/1 var(--font-sans);font-variant-numeric:tabular-nums;color:var(--text);
  background:var(--field);border:1px solid var(--field-border);border-radius:var(--radius-md);caret-color:var(--accent);
  transition:border-color var(--dur-hover) var(--ease-standard),box-shadow var(--dur-hover) var(--ease-standard)}
.sf-code__box.is-split{margin-left:var(--space-3)}
.sf-code__box:hover{border-color:var(--border-strong)}
.sf-code__box:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--highlight)}
.sf-code.is-full .sf-code__box{border-color:var(--accent)}
.sf-code.is-error .sf-code__box{border-color:var(--error-text);box-shadow:0 0 0 3px var(--error-tint)}
@media (max-width:420px){.sf-code{gap:6px}.sf-code__box{width:38px;height:46px;font-size:20px}.sf-code__box.is-split{margin-left:var(--space-2)}}
/* Password rules (x-sf.password-rules): grey circles turn into green checks while typing */
.sf-pass-rules{list-style:none;margin:var(--space-2) 0 0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px var(--space-4);font:var(--ui-body);color:var(--text-2)}
.sf-pass-rules li{display:flex;align-items:center;gap:var(--space-2);transition:color var(--dur-fast) var(--ease-standard)}
.sf-pass-rules__mark{display:inline-grid;place-items:center;flex:none;width:16px;height:16px;border-radius:50%;border:1.5px solid var(--border-strong);color:transparent;
  transition:background-color var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard)}
.sf-pass-rules li.is-met{color:var(--success-text)}
.sf-pass-rules li.is-met .sf-pass-rules__mark{background:var(--success);border-color:var(--success);color:var(--text-on-accent)}
.sf-pass-rules .is-note{grid-column:1/-1;color:var(--text-3);font:var(--ui-meta)}
@media (max-width:560px){.sf-pass-rules{grid-template-columns:1fr}}
/* The authenticator-code dialog (sofonn/_two-factor-confirm, inside the shared SweetAlert) */
.sf-2fa{display:flex;flex-direction:column;align-items:center;gap:var(--space-4);padding-top:var(--space-2)}
.sf-2fa__icon{display:grid;place-items:center;width:48px;height:48px;border-radius:var(--radius-lg);background:var(--info-tint);color:var(--accent-text)}
.sf-2fa__text{margin:0;font:var(--ui-body);color:var(--text-2);text-align:center}
.sf-2fa__text b{display:block;margin-top:2px;color:var(--text);font-weight:600}
.sf-2fa__recovery{width:100%;max-width:300px}
.sf-2fa__switch{all:unset;cursor:pointer;font:var(--ui-label);color:var(--accent-text);border-radius:var(--radius-xs)}
.sf-2fa__switch:hover{text-decoration:underline}
.sf-2fa__switch:focus-visible{box-shadow:var(--focus-ring)}
/* the dialog never scrolls: SweetAlert's html container is overflow:auto and the focus rings / 52 px boxes tipped it over */
.sf-2fa-popup.swal2-popup{max-width:calc(100vw - 32px);padding:var(--space-6) var(--space-6) var(--space-5)}
.sf-2fa-popup .swal2-html-container{overflow:visible;margin:var(--space-2) 0 0;padding:0 var(--space-1)}
.sf-2fa-popup .swal2-validation-message{margin:var(--space-3) 0 0;border-radius:var(--radius-md)}

/* x-sf.fold (owner 2026-10-29, daily report): a block folded to one line; colour = state (error = must fix, warning = waiting,
   info = to check, success = all done), arrow turns when open, the body scrolls inside itself so the page below barely moves */
.sf-fold{border-radius:var(--radius-lg);border:1px solid transparent;background:var(--sf-fold-bg,var(--surface-2))}
.sf-fold.is-info{--sf-fold-bg:var(--info-tint)}.sf-fold.is-info>.sf-fold__head>.sf-icon:first-child{color:var(--info-text)}
.sf-fold.is-success{--sf-fold-bg:var(--success-tint)}.sf-fold.is-success>.sf-fold__head>.sf-icon:first-child{color:var(--success-text)}
.sf-fold.is-warning{--sf-fold-bg:var(--warning-tint)}.sf-fold.is-warning>.sf-fold__head>.sf-icon:first-child{color:var(--warning-text)}
.sf-fold.is-error{--sf-fold-bg:var(--error-tint)}.sf-fold.is-error>.sf-fold__head>.sf-icon:first-child{color:var(--error-text)}
.sf-fold__head{display:flex;align-items:center;gap:var(--space-3);box-sizing:border-box;height:44px;padding:0 var(--space-4);cursor:pointer;list-style:none}
.sf-fold__head::-webkit-details-marker{display:none}
.sf-fold.is-flat>.sf-fold__head{cursor:default}
.sf-fold__title{flex:none;font:var(--ui-label);font-weight:600;color:var(--text);white-space:nowrap}
.sf-fold__summary{flex:0 1 auto;min-width:0;max-width:60ch;font:var(--ui-meta);color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}   /* short: the line never runs on (owner 2026-10-29) */
.sf-fold__action{flex:none;display:flex;gap:var(--space-2);margin-left:auto}
.sf-fold__action .sf-btn{height:28px;min-height:28px;padding-block:0}   /* every folded line the same height, button or not */
.sf-fold__title+.sf-fold__arrow,.sf-fold__summary+.sf-fold__arrow{margin-left:auto}
.sf-fold__arrow{flex:none;color:var(--text-2);transition:transform var(--dur-fast,120ms) ease}
.sf-fold[open]>.sf-fold__head>.sf-fold__arrow{transform:rotate(90deg)}
.sf-fold__body{max-height:var(--sf-fold-max,280px);overflow:auto;padding:0 var(--space-4) var(--space-3);border-top:1px solid var(--divider)}
.sf-fold__body>.sf-alert__list{margin-top:0}
@media (max-width:640px){.sf-fold__summary{display:none}}

/* One standard for the daily report's alert lists (owner 2026-10-29): the stage's colour dot on its filter, a tag on the right (x-sf.alert-tag, ⓘ for "a matter of emission"), replies as a short conversation
   (x-sf.convo: captain grey, office blue). Orange = to answer, red = follow-up / holds approval, blue = replied, green = closed. */
.sf-app :is(button[data-stage],button[data-xc-stage],button[data-rob-stage]):not([data-stage="all"],[data-xc-stage="all"],[data-rob-stage="all"])::before{content:"";display:inline-block;width:8px;height:8px;margin-right:6px;border-radius:50%;background:var(--sf-dot,var(--warning));vertical-align:1px}
.sf-app :is(button[data-stage="follow_up"],button[data-xc-stage="follow_up"],button[data-rob-stage="follow_up"]){--sf-dot:var(--error)}
.sf-app :is(button[data-stage="replied"],button[data-xc-stage="replied"],button[data-rob-stage="replied"]){--sf-dot:var(--info)}   /* replied = blue, not replied = orange (owner 2026-10-30) */
.sf-app :is(button[data-stage="closed"],button[data-xc-stage="closed"],button[data-rob-stage="closed"]){--sf-dot:var(--success)}
/* x-sf.stage-chips (owner 2026-11-01): the office alert pages' stage bar, the same dots; All and Office action needed have none */
.sf-app [data-sf-stage]:not([data-sf-stage="all"],[data-sf-stage="review"])::before{content:"";display:inline-block;flex:none;width:8px;height:8px;margin-right:6px;border-radius:50%;background:var(--sf-dot,var(--warning));vertical-align:1px}
.sf-app [data-sf-stage="replied"]{--sf-dot:var(--info)}
.sf-app [data-sf-stage="follow_up"]{--sf-dot:var(--error)}
.sf-app [data-sf-stage]:is([data-sf-stage="closed"],[data-sf-stage="history"]){--sf-dot:var(--success)}
.sf-app [data-sf-stage][aria-pressed="true"]::before{box-shadow:0 0 0 1.5px var(--text-on-accent)}
.sf-atag{margin-left:auto;flex:none;padding:1px var(--space-2);border-radius:var(--radius-pill,999px);font:var(--ui-meta);white-space:nowrap}
.sf-atag.is-warning{background:var(--warning-tint);color:var(--warning-text)}.sf-atag.is-error{background:var(--error-tint);color:var(--error-text)}
.sf-atag.is-info{background:var(--info-tint);color:var(--info-text)}.sf-atag.is-success{background:var(--success-tint);color:var(--success-text)}
.sf-atag-info{flex:none;align-self:center}
.sf-convo{display:flex;flex-direction:column;gap:var(--space-1);margin-top:var(--space-1)}   /* the text runs to the end of the line (owner 2026-10-29) */
.sf-convo__msg{display:grid;grid-template-columns:56px minmax(0,1fr);gap:var(--space-2);align-items:start}
.sf-convo__txt{justify-self:start}
.sf-convo__who{font:var(--ui-meta);color:var(--text-3);text-align:right;padding-top:3px}
.sf-convo__txt{padding:var(--space-1) var(--space-2);border-radius:var(--radius-md);background:var(--surface-2);font:var(--ui-body);color:var(--text);white-space:pre-line}
.sf-convo__msg.is-office .sf-convo__txt{background:var(--info-tint)}
.sf-convo__who.is-btn{display:inline-flex;align-items:center;justify-content:flex-end;gap:4px;border:0;background:none;padding:3px 0 0;cursor:pointer;color:var(--accent-text,var(--accent))}
.sf-convo__who.is-btn:hover{text-decoration:underline}
/* inside a folded block the block scrolls: a list never scrolls a second time inside it (owner 2026-10-29) */
.sf-app .sf-fold__body .rh-alerts-list{max-height:none;overflow:visible;padding-right:0;outline:none}
/* the stage filter stays on top while the folded block scrolls (owner 2026-10-30): the block's own colour, laid on the page so the rows never show through */
.sf-app .sf-fold__body .rh-alerts-head{position:sticky;top:0;z-index:1;background:linear-gradient(var(--sf-fold-bg,var(--surface-2)),var(--sf-fold-bg,var(--surface-2))),var(--bg)}

/* no side bar on an alert: its tag says where it stands (owner 2026-10-29) */
.sf-app .sf-fold__body .rh-alert:is(.is-emission,.is-closeout){border-inline-start:0;padding-inline-start:0}

/* the answer: one box, Save reply on its right, on every daily-report alert list (owner 2026-10-29) */
.sf-app .sf-fold .rh-reply{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-2);align-items:start;margin-top:var(--space-2)}

/* x-sf.verdict-done (owner 2026-10-29): a verdict already given reads as done, who and when; the form waits behind Change verdict */
.sf-verdict-done{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-verdict-done__head{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);margin:0}
.sf-verdict-done__head .sf-atag{margin-left:0}
.sf-verdict-done__edit>summary{list-style:none;cursor:pointer;width:max-content}
.sf-verdict-done__edit>summary::-webkit-details-marker{display:none}
.sf-verdict-done__edit[open]>summary{margin-bottom:var(--space-2)}

/* x-sf.alert-story (owner 2026-10-30): an alert's history, the daily report's colours: orange not replied, blue replied,
   red sent back or wrong, green ended; a dashed last line while open */
.sf-story{list-style:none;margin:0;padding:0}
.sf-story li{position:relative;padding:0 0 var(--space-3) var(--space-5);font:var(--ui-body);color:var(--text)}
.sf-story li::before{content:"";position:absolute;left:3px;top:5px;width:9px;height:9px;border-radius:50%;background:var(--text-3)}
.sf-story li::after{content:"";position:absolute;left:7px;top:16px;bottom:0;width:1px;background:var(--divider)}
.sf-story li:last-child::after{display:none}
.sf-story li:is(.k-detected,.k-recomputed)::before{background:var(--warning)}
.sf-story li:is(.k-replied,.k-notified)::before{background:var(--info)}
.sf-story li:is(.k-follow_up,.k-not_justified)::before{background:var(--error)}
.sf-story li:is(.k-justified,.k-resolved,.k-auto_resolved)::before{background:var(--success)}
.sf-story li.k-pending::before{background:transparent;border:1.5px dashed var(--text-3);width:8px;height:8px}
.sf-story li.k-pending b{color:var(--text-3);font-weight:600}
.sf-story__at{display:block;font:var(--ui-meta);color:var(--text-2)}
.sf-story q{display:block;margin-top:var(--space-1);color:var(--text-2);white-space:pre-line}
.sf-story q::before,.sf-story q::after{content:none}
.sf-convo__meta{display:block;margin-top:2px;font:var(--ui-meta);color:var(--text-2)}   /* by whom and when (owner 2026-10-30) */
.sf-atag+.sf-atag--after{margin-left:var(--space-1)}   /* Corrected · Not justified side by side */
/* the answer box in a daily-report alert is as small as Running Hours' (owner 2026-10-30): two lines, no counter room */
.sf-app .sf-fold .rh-reply .sf-textarea textarea{min-height:44px;padding:8px 12px;font:var(--ui-body)}
.sf-app .sf-fold .rh-reply .sf-textarea [data-sf-counter],.sf-app .sf-fold .rh-reply .sf-textarea .sf-textarea__count{display:none}
/* Z-16 GPS answer (owner 2026-11-07): small, on the alert's own line, before its status */
.sf-app .rh-alert-line .ts-gps-ask{display:inline-flex;align-items:center;gap:var(--space-2);margin-left:auto}
.sf-app .rh-alert-line .ts-gps-ask__q{font:var(--ui-meta);color:var(--text-2);white-space:nowrap}
.sf-app .rh-alert-line .ts-gps-ask .sf-segmented__opt span{height:22px;padding:0 8px;font-size:11.5px}
.sf-app .rh-alert-line .ts-gps-ask .sf-segmented{height:auto;padding:1px;gap:0}
.sf-app .rh-alert-line .ts-gps-done{display:inline-flex;align-items:center;gap:var(--space-1);margin-left:auto;padding:0 8px;height:22px;border:1px solid var(--border);border-radius:var(--radius-pill);background:transparent;font:var(--ui-meta);color:var(--text-2);cursor:pointer;transition:background var(--dur-hover) var(--ease-standard)}
.sf-app .rh-alert-line .ts-gps-done b{color:var(--text);font-weight:600}
.sf-app .rh-alert-line .ts-gps-done:hover{background:var(--surface-2)}
.sf-app .rh-alert-line:has(.ts-gps-ask) .ts-xc-text{flex-basis:100%}
.sf-app .sf-fold .rh-alert-line .ts-xc-reply{flex:1 1 320px;margin-top:0;align-items:center}
.sf-app .sf-fold .ts-xc-reply .ts-new-loc{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:var(--space-2)}
.sf-atag.is-action{display:inline-flex;align-items:center;gap:4px;border:0;cursor:pointer;font-weight:600}   /* To answer: click to answer */
.sf-atag.is-action:hover{filter:brightness(1.15)}
.sf-atag.is-action:focus-visible{outline:none;box-shadow:var(--focus-ring)}
/* "Back to …" (owner 2026-10-31): came here from another page to fix something; one neutral pill to the exact place, sticky under the header */
.sf-return{position:sticky;top:calc(var(--header-h,64px) + var(--space-2));z-index:40;display:inline-flex;align-items:center;gap:var(--space-2);margin:0 0 var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-pill);border:1px solid var(--glass-border);background:var(--surface-elevated);color:var(--text);font:var(--ui-label);text-decoration:none;transition:background var(--dur-hover) var(--ease-standard)}
.sf-return:hover{background:var(--surface-2);text-decoration:none}

/* ---------- Motion (owner 2026-11-03: reel "Why premium apps feel smooth", @motion_ui_interface; Reel picked over Calm) ----------
   App-wide on Sofonn pages. Hover stays 80 ms; these are the moments that move: press, pull, roll, drag, expand, success.
   The values live here (brand/tokens.json is not on every machine); a reduced-motion device gets none of it.
   Script: sofonn-motion.js (roll, sortable, pull, success; pull to refresh on the page in the installed / Android app). */
:root{--m-press:.95;--m-down:80ms;--m-up:420ms cubic-bezier(.34,1.56,.64,1);--m-pull:.35;--m-back:420ms cubic-bezier(.34,1.56,.64,1);
  --m-roll:700ms;--m-roll-ease:cubic-bezier(.34,1.3,.64,1);--m-roll-gap:100ms;--m-lift:1.05;--m-slide:200ms;--m-expand:350ms;--m-expand-ease:cubic-bezier(.16,1,.3,1);--m-circle:270ms;--m-tick:200ms;--m-chart:350ms;--m-chart-gap:30ms}
@media (prefers-reduced-motion:reduce){:root{--m-chart:0ms;--m-chart-gap:0ms;--m-press:1;--m-up:0ms linear;--m-back:0ms linear;--m-roll:0ms;--m-roll-gap:0ms;--m-lift:1;--m-slide:0ms;--m-expand:0ms;--m-circle:0ms;--m-tick:0ms}}

/* 01 Press: every button sinks fast and springs back on --m-up. Mouse and touch: on touch it is the only sign a tap landed. */
/* `scale`, not transform: buttons placed with a transform (search clear, map buttons) keep their place while pressed. */
.sf-btn{transition:background var(--dur-hover) var(--ease-standard),border-color var(--dur-hover) var(--ease-standard),color var(--dur-hover) var(--ease-standard),scale var(--m-up)}
.sf-btn:active{scale:var(--m-press);transition-duration:var(--dur-hover),var(--dur-hover),var(--dur-hover),var(--m-down);transition-timing-function:var(--ease-standard)}

/* 02 Pull to refresh: the content follows the finger at --m-pull (35 %), the spinner shows as it comes, release past 56 px refreshes.
   .sf-pull = a list of its own; the page itself (installed app / Android app) = body.sf-pull-page moving .sf-main. */
.sf-pull{position:relative;overflow:hidden;border-radius:var(--radius-md)}
.sf-pull__scroll{max-height:var(--h,240px);overflow-y:auto;overscroll-behavior:contain}
.sf-pull__body{translate:0 var(--y,0px);transition:translate var(--m-back)}
.sf-pull.is-pulling .sf-pull__body{transition:none}
.sf-pull__spin{position:absolute;top:12px;left:50%;translate:-50% 0;opacity:var(--o,0);pointer-events:none}
.sf-pull:not(.is-refreshing) .sf-pull__spin .sf-spinner,.sf-pull-spin:not(.is-refreshing) .sf-spinner{animation-play-state:paused;rotate:calc(var(--o,0) * 270deg)}
.sf-pull-page .sf-main{translate:0 var(--y,0px);transition:translate var(--m-back)}
.sf-pull-page.is-pulling .sf-main{transition:none}
.sf-pull-page{overscroll-behavior-y:contain}
.sf-pull-spin{position:fixed;left:50%;top:calc(env(safe-area-inset-top,0px) + 88px);z-index:60;translate:-50% 0;display:grid;place-items:center;width:36px;height:36px;border-radius:50%;
  background:var(--glass-fill);border:1px solid var(--glass-border);color:var(--accent-text);opacity:var(--o,0);pointer-events:none}

/* 03 Rolling number: each changed digit rolls on its own column, --m-roll-gap apart (right to left); [data-sf-roll] = automatic.
   The digit itself stays the element's text (sized, painted transparent); its column 0-9 is the ::after, so scripts and screen readers read the value. */
.sf-roll{white-space:nowrap}   /* the figure's own box is left alone (some are block divs with their own line height) */
.sf-roll__c,.sf-roll__d{display:inline-block;height:1em;line-height:1;vertical-align:-.135em}   /* -.135em = Inter's baseline in a 1em box */
.sf-roll__c{white-space:pre}   /* a space keeps its width in its own box ("143/600 m² free") */
.sf-roll__d{position:relative;overflow:hidden;-webkit-text-fill-color:transparent}
.sf-roll__d::after{content:"0\A 1\A 2\A 3\A 4\A 5\A 6\A 7\A 8\A 9";white-space:pre;position:absolute;inset:0 0 auto;text-align:center;-webkit-text-fill-color:currentColor;
  transform:translateY(calc(var(--n,0) * -1em));transition:transform var(--m-roll) var(--m-roll-ease) var(--delay,0ms)}

/* 04 Drag to reorder: the row lifts (--m-lift, a lighter surface, never a shadow), the others slide aside on --m-slide. */
.sf-sort{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-2)}
.sf-sort__row{position:relative;display:flex;align-items:center;gap:var(--space-3);height:44px;padding:0 var(--space-2) 0 var(--space-3);border-radius:var(--radius-md);
  border:1px solid var(--divider);background:var(--surface-2);font:var(--ui-label);color:var(--text);transition:translate var(--m-slide) var(--ease-standard),scale var(--m-up),background var(--dur-hover) var(--ease-standard)}
.sf-sort__row.is-lifted{z-index:2;scale:var(--m-lift);background:var(--surface-elevated);border-color:var(--border-strong);transition:scale var(--m-slide) var(--ease-standard),background var(--dur-hover) var(--ease-standard)}
.sf-sort__row.is-settling{z-index:2}
.sf-sort.is-still .sf-sort__row{transition:none}
.sf-sort__grip{margin-left:auto;cursor:grab;touch-action:none}
.sf-sort__row.is-lifted .sf-sort__grip{cursor:grabbing}

/* 05 Expand: every fold opens fast, then slow (--m-expand). CSS only (::details-content); a browser without it opens at once. */
details:is(.sf-fold,.sf-card){interpolate-size:allow-keywords}
details:is(.sf-fold,.sf-card)::details-content{block-size:0;overflow-y:clip;transition:block-size var(--m-expand) var(--m-expand-ease),content-visibility var(--m-expand) allow-discrete}
details:is(.sf-fold,.sf-card)[open]::details-content{block-size:auto}
:is(.sf-fold__arrow,.sf-card__arrow){transition:transform var(--m-expand) var(--m-expand-ease)}

/* 06 Success: the circle draws, then the tick (--m-circle + --m-tick). Real "done" moments only (approve, close). */
.sf-done{display:block;width:56px;height:56px;flex:none}
.sf-done :is(circle,path){fill:none;stroke:var(--success);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1}
.sf-done circle{animation:sf-draw var(--m-circle,0ms) var(--ease-standard) forwards}
.sf-done path{stroke-width:3.5;animation:sf-draw var(--m-tick,0ms) var(--ease-standard) var(--m-circle,0ms) forwards}
.sf-toast.has-done{display:flex;align-items:center;gap:var(--space-3)}
.sf-toast__done{flex:none}
.sf-toast__done .sf-done{width:28px;height:28px}
@keyframes sf-draw{to{stroke-dashoffset:0}}

/* 07 Charts (owner 2026-11-03; not in the reel, its "fast then slow" + "roll, don't jump"): every chart appears ease-out in
   --m-chart, marks spread over at most 360 ms; live data moves from the old values (never a redraw from zero); hover is
   instant. Chart.js + ApexCharts defaults: sofonn-chart-motion.js (layout <head>). Progress fills grow in, then slide. */
.sf-progress__fill{transition:width var(--m-chart) var(--m-expand-ease)}
@starting-style{.sf-progress__fill{width:0}}
.sf-chart-box{position:relative;height:160px;min-width:0}

/* The gallery's Motion card: one tile per detail. */
.sf-motion-demo{display:flex;flex-direction:column;gap:var(--space-3);min-width:0;padding:var(--space-4);border-radius:var(--radius-lg);border:1px solid var(--divider);background:var(--surface)}
.sf-motion-demo__title{margin:0;font:var(--ui-card-title)}
.sf-motion-demo__stage{display:flex;flex-direction:column;justify-content:center;gap:var(--space-3);min-height:170px}
.sf-motion-demo__rule{margin:0;font:var(--ui-meta);color:var(--accent-text)}

/* Map full screen (map-fullscreen.js, owner 2026-11-03). .sf-fs = the page's own full screen where the browser has none
   (iPhone, the Android app): the element covers the page. .sf-fs-active = full screen either way. */
html.sf-fs-on,html.sf-fs-on body{overflow:hidden}
html.sf-fs-on .gs-help{display:none}
.sf-fs-host{z-index:1051!important}.sf-fs-host-rel{position:relative}   /* map-fullscreen.js lift(): the covering element's parents above the sticky top bar */   /* the floating help "?" sat over the map's own controls */
.sf-fs{position:fixed!important;inset:0!important;z-index:1051!important;width:auto!important;height:100dvh!important;max-height:none!important;margin:0!important;border-radius:0!important;background:var(--bg)}
.sf-fs-btn{position:absolute;z-index:1100;right:calc(12px + env(safe-area-inset-right,0px));display:grid;place-items:center;width:40px;height:40px;padding:0;border-radius:50%;border:1px solid var(--glass-border);background:var(--glass-fill);color:var(--text);font:600 16px/1 var(--font-sans);cursor:pointer;box-shadow:var(--shadow-e1);transition:background var(--dur-hover) var(--ease-standard)}
.sf-fs-btn:hover{background:var(--surface-solid)}
.sf-fs-btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.sf-fs-close{top:calc(12px + env(safe-area-inset-top,0px))}
.sf-fs-turn{top:calc(60px + env(safe-area-inset-top,0px))}
.sf-fs-turn[aria-pressed="true"]{color:var(--accent-text)}
.sf-fs-tip{position:absolute;z-index:1100;left:50%;bottom:calc(16px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);max-width:calc(100% - 32px);padding:8px 14px;border-radius:var(--radius-pill);border:1px solid var(--glass-border);background:var(--glass-fill);color:var(--text);font:var(--ui-label);text-align:center;pointer-events:none}
/* the ✕ (and ⟲) take the top-right corner: the map's own top-right controls move down under them */
.sf-fs-active .leaflet-top.leaflet-right{top:52px}
.sf-fs-active:has(> .sf-fs-turn) .leaflet-top.leaflet-right{top:100px}

/* ===== Dashboard Studio (spec 2026-11-07): top bar, then three panes — library | the two previews | settings. It fills the window below
   the header (--sf-studio-top, set by sofonn-dashboard-studio.js); the panes and the previews scroll, the page does not.
   The app sidebar steps aside on wide screens (a full-screen tool; Cancel goes back). Below 1024px only the note. ===== */
.sf-main:has(.sf-studio){padding-bottom:0}
@media (min-width:1280px){.sf-shell:has(.sf-studio){grid-template-columns:minmax(0,1fr)}.sf-shell:has(.sf-studio) .sf-sidebar{display:none}
  .sf-shell:has(.sf-studio) .sf-main{grid-column:1/-1}}   /* whatever the column template (the rail's 64px one wins on specificity) */
.sf-studio{--sf-studio-lib:256px;--sf-studio-set:296px;display:flex;flex-direction:column;gap:var(--space-3);height:max(560px,calc(100vh - var(--sf-studio-top,136px) - var(--space-4)));min-width:0}
.sf-studio__bar{display:flex;align-items:center;gap:var(--space-4);flex-wrap:wrap;min-width:0}
.sf-studio__title{margin:0;font:var(--ui-title);letter-spacing:var(--track-title);color:var(--text)}
.sf-studio__actions{display:flex;align-items:center;gap:var(--space-2);margin-inline-start:auto}
.sf-studio__dirty{display:inline-flex;align-items:center;gap:var(--space-2);margin-inline-end:var(--space-2);font:var(--ui-label);color:var(--text-2)}
.sf-studio__dirty::before,.sf-studio__bar .sf-segmented__btn.is-dirty::after{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:var(--warning)}
.sf-studio__panes{display:grid;grid-template-columns:var(--sf-studio-lib) minmax(0,1fr) var(--sf-studio-set);gap:var(--space-3);flex:1;min-height:0}
.sf-studio__pane{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden;border:1px solid var(--glass-border);border-radius:var(--radius-xl);background:var(--glass-fill)}
.sf-studio__pane-title{display:flex;align-items:baseline;gap:var(--space-2);margin:0;font:var(--ui-card-title);color:var(--text)}
.sf-studio__count{margin-inline-start:auto;font:var(--ui-meta);color:var(--text-3);font-variant-numeric:tabular-nums}
.sf-studio__label{margin:0;font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-3)}
.sf-studio__empty{margin:var(--space-4) var(--space-2);font:var(--ui-body);color:var(--text-3)}

/* Library: by area, a search; each row = kind thumbnail, title, status line, the eye. Selected = the highlight tint, never a second primary. */
.sf-studio-lib__head{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4) var(--space-4) var(--space-3);border-bottom:1px solid var(--divider)}
.sf-studio-lib .sf-input{height:var(--control-sm);padding:0 var(--space-3);gap:var(--space-2)}
.sf-studio-lib__list{flex:1;min-height:0;overflow-y:auto;padding:0 var(--space-2) var(--space-4)}
.sf-studio__area{margin:0;padding:var(--space-4) var(--space-2) var(--space-2);font:var(--ui-section);letter-spacing:var(--track-section);text-transform:uppercase;color:var(--text-3)}
.sf-studio-items{display:flex;flex-direction:column;gap:2px;margin:0;padding:0;list-style:none}
.sf-studio-item{display:flex;align-items:center;gap:var(--space-1);border-radius:var(--radius-md);transition:background var(--dur-hover) var(--ease-standard)}
.sf-studio-item:hover{background:var(--surface-2)}
.sf-studio-item.is-selected{background:var(--highlight)}
.sf-studio-item__main{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:var(--space-3);flex:1;min-width:0;padding:var(--space-2);border-radius:var(--radius-md);cursor:pointer}
.sf-studio-item__main:focus-visible{box-shadow:var(--focus-ring)}
.sf-studio-item__text{display:flex;flex-direction:column;gap:2px;min-width:0}
.sf-studio-item__title{font:500 13px/1.3 var(--font-sans);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-studio-item__status{font:var(--ui-meta);color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sf-studio-item.is-selected .sf-studio-item__title{color:var(--accent-text)}
.sf-studio-item.is-off :is(.sf-studio-thumb,.sf-studio-item__title){opacity:.5}
.sf-studio-item.is-na .sf-studio-item__status{color:var(--warning-text)}
.sf-studio-item__eye{flex:none;margin-inline-end:var(--space-1);color:var(--text-3)}
.sf-studio-item.is-off .sf-studio-item__eye{color:var(--text-2)}
.sf-studio-thumb{flex:none;display:grid;place-items:center;width:44px;height:32px;border-radius:var(--radius-sm);border:1px solid var(--divider);background:var(--surface);color:var(--text-3)}
.sf-studio-thumb svg{display:block;width:34px;height:24px}
.sf-studio-item.is-selected .sf-studio-thumb{color:var(--accent-text);border-color:color-mix(in srgb,var(--accent) 30%,transparent)}

/* The previews: desktop (1440 px iframe scaled to its screen) beside the phone (390 px in a device outline, ~0.6 scale); each loads on its own.
   Below 1280px one at a time, by the Desktop | Phone switch (both stay loaded; the ResizeObserver refits the one shown). */
.sf-studio__canvas{flex-direction:row;gap:var(--space-4);padding:var(--space-4)}
.sf-studio__canvas-head{display:none}
.sf-studio__canvas-head .sf-segmented{height:var(--control-sm);padding:2px}
.sf-studio__canvas-head .sf-segmented__btn{height:26px;padding:0 12px;font-size:12px}
.sf-studio-frame{display:flex;flex-direction:column;gap:var(--space-2);min-width:0;min-height:0}
.sf-studio-frame.is-desktop{flex:1 1 0}
.sf-studio-frame.is-phone{flex:none;width:252px}   /* 236px screen inside the bezel = 0.6 of 390 */
.sf-studio-frame__head{display:flex;align-items:center;gap:var(--space-2);height:20px;padding:0 var(--space-1);font:var(--ui-label);color:var(--text-2)}
.sf-studio-frame__head .sf-spinner{display:none}
.sf-studio-frame.is-loading .sf-studio-frame__head .sf-spinner{display:inline-block}
.sf-studio-frame__meta{margin-inline-start:auto;font:var(--ui-meta);color:var(--text-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.sf-studio-frame__screen{position:relative;flex:1;min-height:0;overflow:hidden;border-radius:var(--radius-lg);border:1px solid var(--divider);background:var(--bg)}
.sf-studio-frame.is-phone .sf-studio-frame__screen{border-radius:var(--radius-2xl);border:var(--space-2) solid var(--surface-elevated);box-shadow:0 0 0 1px var(--border-strong)}   /* the device outline: bezel + hairline */
.sf-studio-frame__screen iframe{position:absolute;top:0;left:0;display:block;border:0;transform-origin:0 0;background:var(--bg);transition:opacity var(--m-slide) var(--ease-standard)}
.sf-studio-frame:is(.is-loading,.is-failed) iframe{opacity:0}
.sf-studio-frame__load{position:absolute;inset:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));align-content:start;gap:var(--space-3);padding:var(--space-4);opacity:0;pointer-events:none;transition:opacity var(--m-slide) var(--ease-standard)}
.sf-studio-frame.is-loading .sf-studio-frame__load{opacity:1}
.sf-studio-frame__load .sf-skeleton{width:auto;height:44px;border-radius:var(--radius-md)}
.sf-studio-frame__load .is-wide{grid-column:span 2;height:132px}
.sf-studio-frame__load .is-full{grid-column:1/-1;height:96px}
.sf-studio-frame__load .is-half{height:132px}
.sf-studio-frame.is-phone .sf-studio-frame__load{grid-template-columns:repeat(2,minmax(0,1fr));padding:var(--space-3);gap:var(--space-2)}
.sf-studio-frame.is-phone .sf-studio-frame__load :is(.is-wide,.is-full,.is-half){grid-column:1/-1;height:110px}
.sf-studio-frame__fail{position:absolute;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);padding:var(--space-4);text-align:center;font:var(--ui-body);color:var(--text-2)}
.sf-studio-frame__fail p{margin:0}
.sf-studio-frame.is-failed .sf-studio-frame__fail{display:flex}
.sf-dash-board.is-studio.is-phone-preview>.sf-dash-slot{cursor:pointer}   /* the phone preview: a tap selects, no drag */

/* Settings of the selected card: switches, width chips (allowed only), height steps, place, the tablet / phone note. */
[data-studio-settings]{overflow-y:auto}
.sf-studio-set{display:flex;flex-direction:column;gap:var(--space-5);padding:var(--space-4)}
.sf-studio-set__head{display:flex;align-items:center;gap:var(--space-3)}
.sf-studio-set__name{flex:1;min-width:0}
.sf-studio-set__title{margin:0;font:var(--ui-card-title);color:var(--text);overflow-wrap:anywhere}
.sf-studio-set__meta{margin:2px 0 0;font:var(--ui-meta);color:var(--text-3)}
.sf-studio-set__lead{margin:calc(var(--space-3) * -1) 0 0;font:var(--ui-body);color:var(--text-2)}
.sf-studio-set__group{display:flex;flex-direction:column;gap:var(--space-2)}
.sf-studio-set__switches{display:flex;flex-direction:column;padding:var(--space-1) var(--space-3);border-radius:var(--radius-lg);border:1px solid var(--divider);background:var(--surface)}
.sf-studio-set__switches .sf-switch-row:first-child{padding-top:9px}
.sf-studio-set__switches .sf-switch:disabled{opacity:.38;cursor:not-allowed}
.sf-studio-chips{padding:3px;border-radius:var(--radius-md);border:1px solid var(--glass-border);background:color-mix(in srgb,var(--field) 55%,transparent)}
.sf-studio-chips button:disabled{opacity:.38;cursor:not-allowed;background:none}
.sf-studio-set__hint{margin:0;font:var(--ui-meta);color:var(--text-3)}
.sf-studio-set__moves{display:flex;gap:var(--space-2)}
.sf-studio-set__moves .sf-btn{flex:1 1 0;min-width:0}
.sf-studio-set__note{display:flex;align-items:flex-start;gap:var(--space-2);margin:0;padding:var(--space-3);border-radius:var(--radius-md);border:1px solid var(--divider);background:var(--surface);font:var(--ui-body);color:var(--text-2)}
.sf-studio-set__note .sf-icon{flex:none;margin-top:1px;color:var(--text-3)}
.sf-studio-set__note.is-warn{border-color:transparent;background:var(--warning-tint);color:var(--warning-text)}
.sf-studio-set__note.is-warn .sf-icon{color:currentColor}
.sf-studio-rules{display:flex;flex-direction:column;gap:var(--space-3);margin:calc(var(--space-3) * -1) 0 0;padding:0;list-style:none;font:var(--ui-body);color:var(--text-2)}
.sf-studio-rules li{display:flex;align-items:flex-start;gap:var(--space-2)}
.sf-studio-rules .sf-icon{flex:none;margin-top:1px;color:var(--success-text)}

.sf-studio__narrow{display:none;text-align:center;padding:var(--space-6) var(--space-4);color:var(--text)}
@media (max-width:1279.98px){
  .sf-studio{--sf-studio-lib:224px;--sf-studio-set:264px}
  .sf-studio__canvas{flex-direction:column;gap:var(--space-3)}
  .sf-studio__canvas-head{display:flex}
  .sf-studio__canvas.is-show-phone .sf-studio-frame.is-desktop,.sf-studio__canvas:not(.is-show-phone) .sf-studio-frame.is-phone{display:none}
  .sf-studio-frame.is-phone{flex:1 1 0;width:min(406px,100%);align-self:center}
}
@media (max-width:1023.98px){
  .sf-studio{height:auto}
  .sf-studio__panes,.sf-studio__bar>:not(.sf-studio__title){display:none}
  .sf-studio__narrow{display:block}
}
