/*
 * Creo CTE — front-end styles.
 *
 * MOBILE FIRST. The phone is the primary device: this gets opened standing in
 * a restaurant to add a bill, not at a desk. So the base rules below ARE the
 * phone layout — no min-width query needed to get it — and the two `min-width`
 * blocks at the bottom progressively add breathing room for tablet and desktop.
 * Anything added here must be checked at 320px wide before it is checked
 * anywhere else.
 *
 * Scoped under .cte-* throughout so the plugin can drop into any theme without
 * a fight. The palette is neutral by design: colour is reserved for STATUS —
 * red for overdue, amber for due soon, green for in warranty — because those
 * are what a person opens this app to find out. Spending is just numbers.
 */

:root {
  --cte-bg: #f6f7f9;
  --cte-surface: #ffffff;
  --cte-line: #e3e6ea;
  --cte-text: #1d2127;
  --cte-muted: #6b7480;
  --cte-accent: #2f6fed;
  --cte-positive: #12855a;
  --cte-negative: #c2374b;
  --cte-warn: #9a5b00;
  --cte-radius: 12px;

  /* Page gutter. Tight on a phone so content is not squeezed into a column
     inside a column, and it opens up from the tablet breakpoint. */
  --cte-gutter: 14px;
  /* Minimum comfortable touch target. 44px is the Apple HIG figure and the one
     that stops mis-taps on a moving train. */
  --cte-tap: 44px;
}

/* EVERY root the plugin renders has to be named here, not just .cte-app.
   This has bitten twice: modals are appended to document.body, and the
   signed-out gate used to render outside the app root. Both then missed
   border-box, and the symptom is never obviously a box-model problem — inputs
   silently grew from 44px to 66px tall, and a `width: 100%` button overflowed
   its padded container to the right. If you add another top-level container,
   add it here too. */
.cte-app,
.cte-app *,
.cte-overlay,
.cte-overlay *,
.cte-gate,
.cte-gate * {
  box-sizing: border-box;
}

/* Make the `hidden` attribute actually hide things.
   The browser's built-in rule is `[hidden] { display: none }` — a plain
   attribute selector, which ANY class selector that sets `display` outranks.
   .cte-scan-progress is `display: flex`, so it ignored `hidden` and sat on
   screen from the moment the sheet opened: empty thumbnail, no text, spinner
   running. Nothing in the JS was wrong; the attribute simply had no effect.
   This has to stay ahead of every component rule below. */
.cte-app [hidden],
.cte-overlay [hidden],
.cte-gate [hidden] {
  display: none !important;
}

.cte-app {
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--cte-text);
  background: var(--cte-bg);
  margin: 0;
  min-height: 100vh;
  /* dvh tracks the shrinking viewport as mobile Safari's address bar collapses;
     the vh above stays as the fallback for browsers without it. */
  min-height: 100dvh;
  /* The horizontal clip lives on .cte-wrap rather than here: the fixed bottom
     bar is a child of this element, and an ancestor that clips would cut it
     off entirely. */
}

/* --- the shell: drawer + content ---------------------------------------
 *
 * ON A PHONE the drawer is an overlay: fixed, off-canvas, slid in over the
 * content with a scrim behind it. On a WIDE screen it is a column the content
 * sits beside, and the scrim is gone entirely — there is nothing to dismiss
 * because nothing is covered.
 *
 * One class on <body> drives both, so the JS never needs to know which layout
 * is in play. It toggles cte-drawer-open and the media query decides what that
 * means.
 */
.cte-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  width: 264px;
  max-width: 84vw;
  display: flex;
  flex-direction: column;
  background: var(--cte-surface);
  border-right: 1px solid var(--cte-line);
  padding: 10px 10px calc(10px + env(safe-area-inset-bottom));
  /* Off-canvas by default. transform rather than left, so the slide is
     composited and does not relayout the page on every frame. */
  transform: translateX(-100%);
  transition: transform 0.22s ease;
  overflow-y: auto;
  overscroll-behavior: contain;
}

body.cte-drawer-open .cte-drawer {
  transform: translateX(0);
}

.cte-scrim {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: rgba(16, 20, 26, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}

body.cte-drawer-open .cte-scrim {
  opacity: 1;
  pointer-events: auto;
}

.cte-drawer-brand {
  display: flex;
  align-items: center;
  padding: 10px 10px 14px;
  text-decoration: none;
  color: inherit;
}

.cte-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cte-nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--cte-tap);
  padding: 0 12px;
  border-radius: 10px;
  color: var(--cte-text);
  text-decoration: none;
  font-weight: 500;
}

.cte-nav-item:hover {
  background: var(--cte-bg);
}

.cte-nav-current {
  background: rgba(47, 111, 237, 0.1);
  color: var(--cte-accent);
}

.cte-nav-icon,
.cte-drawer-foot svg {
  width: 19px;
  height: 19px;
  flex: none;
}

.cte-drawer-foot {
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--cte-line);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cte-drawer-foot .cte-nav-item {
  color: var(--cte-muted);
  font-weight: 400;
}

/* --- top bar ------------------------------------------------------------ */

.cte-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 56px;
  padding: 0 var(--cte-gutter);
  background: rgba(246, 247, 249, 0.92);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--cte-line);
}

.cte-menu-btn svg {
  width: 22px;
  height: 22px;
}

.cte-topbar-title {
  font-weight: 650;
  font-size: 17px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cte-topbar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 4px;
}

@media (min-width: 900px) {
  /* The drawer stops overlaying and becomes a column. The content is pushed
     across by the same width, and only while it is open — closing it gives the
     whole width back rather than leaving a gap where it was. */
  .cte-scrim {
    display: none;
  }

  body.cte-drawer-open .cte-main {
    margin-left: 264px;
  }

  .cte-main {
    transition: margin-left 0.22s ease;
  }
}

.cte-wrap {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 14px var(--cte-gutter);
  /* Clears the fixed bottom bar AND the iOS home indicator, so the last trip
     can always be scrolled out from under the button. */
  padding-bottom: calc(104px + env(safe-area-inset-bottom));

  /* Nothing may cause a sideways scroll. On a phone a single overflowing row
     makes the whole page slide, which reads as the app being broken.
     `clip` rather than `hidden` deliberately: `overflow-x: hidden` forces the
     other axis to `auto`, turning this into a scroll container and breaking
     `position: sticky` on the header. A browser too old to know `clip` just
     ignores the line, which loses the belt but keeps the braces, since every
     row already has min-width: 0. The clip margin lets the trip cards' shadows
     breathe past the edge instead of being sliced off. */
  overflow-x: clip;
  overflow-clip-margin: 6px;
}

/* --- header ------------------------------------------------------------ */

.cte-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px var(--cte-gutter);
  padding-top: calc(10px + env(safe-area-inset-top));
  background: var(--cte-surface);
  border-bottom: 1px solid var(--cte-line);
  /* Stays put while a long expense list scrolls, so "back" is always reachable
     without scrolling to the top first. */
  position: sticky;
  top: 0;
  z-index: 20;
}

/* The two side slots share a width so the wordmark sits optically centred
   rather than merely in the middle of whatever space is left over. */
.cte-header-side {
  display: flex;
  align-items: center;
  /* Tight on a phone, where three icons share the slot with a centred
     wordmark; opened up with the labels at 600px. */
  gap: 10px;
  flex: 1 1 0;
  min-width: 0;
}

.cte-header-right {
  justify-content: flex-end;
}

.cte-brand {
  display: block;
  flex: 0 0 auto;
  line-height: 0;
  /* It is a link home, but it is the brand — it should not look like body copy
     with an underline under it. */
  text-decoration: none;
  color: inherit;
}

.cte-brand img {
  display: block;
  height: 22px;
  width: auto;
}

/* Mark and name side by side in the header, stacked on the signed-out gate. */
.cte-brand-lockup {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cte-logo {
  display: block;
  height: 24px;
  width: auto;
}

.cte-gate-mark.cte-brand-lockup {
  flex-direction: column;
  gap: 12px;
  margin-bottom: 24px;
}

.cte-gate-mark .cte-logo {
  height: 62px;
}

.cte-wordmark-text {
  display: block;
  font-size: clamp(17px, 4.5vw, 19px);
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--cte-text);
  white-space: nowrap;
}

.cte-gate-mark .cte-wordmark-text {
  font-size: 26px;
}

/* The back control is an arrow alone on a phone — the label would squeeze the
   wordmark off centre — and gains its text once there is room. */
.cte-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--cte-tap);
  margin-left: -6px;
  padding: 0 6px;
  -webkit-tap-highlight-color: transparent;
}

.cte-back svg {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
}

.cte-back-label { display: none; }

/* The wp-admin and profile links are icons alone on a phone; their labels
   would push the centred wordmark off centre at 320px. */
.cte-icon-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.cte-icon-link svg {
  /* An icon reads as slightly smaller than a letterform at the same size, so it
     gets a little more than the 19px the text beside it occupies. */
  width: 20px;
  height: 20px;
  display: block;
}

.cte-icon-label { display: none; }

/* The person's own name, above the balance. Small and quiet: the number is the
   headline, this is just orientation. */
.cte-greeting {
  margin: 2px 0 10px;
  font-size: 13px;
  color: var(--cte-muted);
}

/* The trip name, moved out of the header so it can wrap instead of truncating
   to a few characters between the back arrow and Log out. */
.cte-page-title {
  margin: 4px 0 12px;
  font-size: clamp(21px, 5.5vw, 26px);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.cte-back,
.cte-logout {
  color: var(--cte-muted);
  text-decoration: none;
  font-size: 13px;
  white-space: nowrap;
}

.cte-back:hover,
.cte-logout:hover {
  color: var(--cte-accent);
}

/* --- headline balance --------------------------------------------------- */

.cte-hero {
  background: var(--cte-surface);
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
  padding: 20px 16px;
  text-align: center;
  margin-bottom: 14px;
}

.cte-hero-amount {
  font-size: clamp(30px, 9vw, 40px);
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.cte-hero.cte-positive .cte-hero-amount { color: var(--cte-positive); }
.cte-hero.cte-negative .cte-hero-amount { color: var(--cte-negative); }

.cte-hero-label {
  color: var(--cte-muted);
  font-size: 14px;
  margin-top: 2px;
}

/* --- sections ----------------------------------------------------------- */

.cte-section {
  background: var(--cte-surface);
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
  padding: 14px;
  margin-bottom: 14px;
}

.cte-section h3 {
  margin: 0 0 10px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cte-muted);
}

.cte-subhead {
  margin: 18px 0 6px;
  font-size: 13px;
  color: var(--cte-muted);
}

.cte-empty {
  color: var(--cte-muted);
  font-size: 14px;
  margin: 8px 0;
}

/* A button introducing a list, rather than sitting in a row of actions. Full
   width on a phone: it is the primary action of that section and a thumb
   should not have to aim for it. */
.cte-section > .cte-btn {
  display: flex;
  width: 100%;
  margin-bottom: 12px;
}

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

.cte-people,
.cte-weeks,
.cte-debts,
.cte-expenses {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cte-person,
.cte-debt {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Tall enough to be a comfortable tap target in its own right. */
  min-height: var(--cte-tap);
  padding: 10px 2px;
  border-bottom: 1px solid var(--cte-line);
}

/* --- swipe-to-delete rows ----------------------------------------------- */

/* The row is now a track: the Delete button sits underneath and only
   .cte-swipe-body moves, so nothing reflows while a finger is down. */
.cte-expense {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--cte-line);
}

.cte-swipe-body {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--cte-tap);
  padding: 10px 2px;
  background: var(--cte-surface);
  transform: translateX(0);
  transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
  /* Tells the browser it still owns vertical scrolling, so a list scrolls on
     the compositor thread until the handler claims a horizontal gesture. */
  touch-action: pan-y;
}

/* No transition while a finger is down — the row must track the finger
   exactly, not lag behind it by the animation duration. */
.cte-swipe-body.cte-dragging {
  transition: none;
}

.cte-swipe.cte-open .cte-swipe-body {
  transform: translateX(-96px);
}

.cte-swipe-action {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 96px;
  display: flex;
}

.cte-swipe-delete {
  flex: 1;
  border: 0;
  background: var(--cte-negative);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 550;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* The × is the affordance for pointer devices, where there is no swipe to
   discover. On touch it only steals width from the title. */
@media (hover: none) {
  .cte-row-delete { display: none; }
}

@media (hover: hover) {
  .cte-swipe-delete:hover { background: #a82c3e; }
}

.cte-expense .cte-icon {
  min-width: var(--cte-tap);
}

.cte-person:last-child,
.cte-expense:last-child,
.cte-debt:last-child {
  border-bottom: 0;
}

/* --- trip cards --------------------------------------------------------- */

/* Each trip is its own raised card with a gap around it and a chevron, rather
   than a row inside one shared block. On touch there is no hover to reveal
   that something is tappable, so the affordance has to be visible at rest. */
.cte-week-card {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 62px;
  margin-bottom: 10px;
  padding: 12px 12px 12px 14px;
  background: var(--cte-surface);
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
  box-shadow: 0 1px 2px rgba(20, 24, 31, 0.05);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.cte-week-card:last-child { margin-bottom: 0; }

/* Presses in, so a tap is acknowledged before the next screen paints. */
.cte-week-card:active {
  background: #f7f9fc;
  transform: scale(0.994);
}

.cte-chevron {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  color: #b6bdc7;
}

/* Smaller on an expense row than on a trip card: the row already carries an
   amount and a share, and this only has to say "there is more here". */
.cte-expense .cte-chevron {
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  margin-left: -2px;
}

/* --- expense detail sheet ----------------------------------------------- */

.cte-detail-amount {
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -0.02em;
  text-align: center;
  margin-bottom: 14px;
}

.cte-detail {
  margin: 0 0 4px;
  border-top: 1px solid var(--cte-line);
}

.cte-detail > div {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--cte-line);
}

.cte-detail dt {
  flex: 0 0 84px;
  color: var(--cte-muted);
  font-size: 13px;
}

.cte-detail dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 14.5px;
}

.cte-detail-notes {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: var(--cte-bg);
  border-radius: 9px;
  font-size: 14px;
}

/* Heading for a list that is not wrapped in a section card. */
.cte-list-head {
  margin: 20px 0 10px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cte-muted);
}

.cte-empty-block {
  background: var(--cte-surface);
  border: 1px dashed var(--cte-line);
  border-radius: var(--cte-radius);
  padding: 20px 16px;
  text-align: center;
  margin: 0;
}

/* --- pinned bottom action ----------------------------------------------- */

.cte-bottom-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  padding: 10px var(--cte-gutter);
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--cte-line);
  /* Translucent so the list reads as continuing underneath rather than ending
     abruptly at the bar. */
  background: rgba(246, 247, 249, 0.88);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* Without backdrop-filter the translucency only looks washed out, so fall back
   to a solid ground. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .cte-bottom-bar { background: var(--cte-bg); }
}

.cte-bottom-bar-inner {
  max-width: 720px;
  margin: 0 auto;
}

.cte-btn-lg {
  width: 100%;
  min-height: 50px;
  font-size: 15.5px;
  font-weight: 550;
  border-radius: 11px;
}

.cte-trip-main,
.cte-expense-main {
  display: flex;
  flex-direction: column;
  flex: 1;
  /* Without this a long title refuses to shrink and pushes the amount off the
     right edge — the single most common cause of a sideways scroll here. */
  min-width: 0;
}

.cte-expense-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  flex: 0 0 auto;
  /* Capped so the amount column cannot crowd the expense title out of
     existence on a narrow screen. */
  max-width: 46%;
}

.cte-expense-right .cte-trip-meta {
  white-space: nowrap;
}

.cte-trip-title,
.cte-expense-title {
  font-weight: 550;
  font-size: 15px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cte-trip-meta {
  color: var(--cte-muted);
  font-size: 12.5px;
}

/* The secondary line truncates like the title above it. Without this the title
   clips to a few characters while the meta below it wraps to four lines, and
   every row ends up a different height. */
.cte-expense-main .cte-trip-meta,
.cte-trip-main .cte-trip-meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cte-person-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cte-amount {
  font-variant-numeric: tabular-nums;
  font-weight: 550;
  white-space: nowrap;
  flex: 0 0 auto;
}

.cte-positive { color: var(--cte-positive); }
.cte-negative { color: var(--cte-negative); }

.cte-pending {
  color: var(--cte-muted);
  font-size: 12px;
  font-style: normal;
}

/* --- avatars & badges --------------------------------------------------- */

.cte-avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: 50%;
  background: #e7ecf6;
  color: #35507f;
  font-size: 11.5px;
  font-weight: 650;
  overflow: hidden;
}

/* The photo sits on top of the initials. If it fails to load — which is what
   Gravatar's 404 default produces for someone with no image — it is removed and
   the initials are simply already there, with nothing to swap in. */
.cte-avatar-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* --- buttons ------------------------------------------------------------ */

.cte-btn {
  font: inherit;
  font-size: 14px;
  /* Several of these are anchors, not <button>s — without this they render
     underlined with the label sitting off-centre. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  min-height: var(--cte-tap);
  padding: 10px 14px;
  border: 1px solid var(--cte-line);
  border-radius: 9px;
  background: var(--cte-surface);
  color: var(--cte-text);
  cursor: pointer;
  /* Stops iOS from flashing a grey box over the button on tap. */
  -webkit-tap-highlight-color: transparent;
}

.cte-btn-primary {
  background: var(--cte-accent);
  border-color: var(--cte-accent);
  color: #fff;
}

.cte-btn-danger {
  background: var(--cte-negative);
  border-color: var(--cte-negative);
  color: #fff;
}

.cte-confirm-text {
  margin: 0;
  color: var(--cte-muted);
  font-size: 14.5px;
}

.cte-btn[disabled] {
  opacity: 0.55;
  cursor: default;
}

.cte-icon {
  border: 0;
  background: none;
  color: var(--cte-muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  /* A bare glyph is a tiny target; this gives it a real one without changing
     how it looks. */
  min-width: var(--cte-tap);
  min-height: var(--cte-tap);
  flex: 0 0 auto;
  -webkit-tap-highlight-color: transparent;
}

/* Hover styling only where a pointer actually exists. On a touch device these
   rules stick after a tap and leave rows looking selected. */
@media (hover: hover) {
  .cte-btn:hover { border-color: #c9ced6; }
  .cte-btn-primary:hover { background: #2560d4; }
  .cte-icon:hover { color: var(--cte-negative); }
  .cte-week-card:hover { background: #fafbfc; }
  /* The body carries the background now, so hovering the track alone would
     never show through it. */
  .cte-expense:hover .cte-swipe-body { background: #fafbfc; }
  .cte-check:hover,
  .cte-split-row:hover { background: #f6f8fb; }
}

/* --- modals ------------------------------------------------------------- */

/* On a phone a modal is a bottom sheet: anchored to the thumb, not floating in
   the middle of the screen out of reach. It becomes a centred dialog from the
   tablet breakpoint down the file. */
.cte-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 31, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 9999;
}

.cte-modal {
  background: var(--cte-surface);
  border-radius: 16px 16px 0 0;
  width: 100%;
  /* Never taller than the screen; the body scrolls inside instead. */
  max-height: 92vh;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 -8px 40px rgba(20, 24, 31, 0.28);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--cte-text);
}

.cte-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--cte-line);
  flex: 0 0 auto;
}

.cte-modal-head h2 {
  margin: 0;
  font-size: 17px;
}

.cte-modal-body {
  padding: 14px;
  /* The one scrolling region, so the title and the submit button stay put
     while a long member list moves. */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  flex: 1 1 auto;
}

.cte-modal-foot {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--cte-line);
  flex: 0 0 auto;
}

/* Full-width split footer buttons on a phone, primary on the right where the
   thumb rests. */
.cte-modal-foot .cte-btn {
  flex: 1;
}

/* --- forms -------------------------------------------------------------- */

.cte-field {
  display: block;
  margin-bottom: 12px;
}

.cte-field > span {
  display: block;
  font-size: 12.5px;
  color: var(--cte-muted);
  margin-bottom: 4px;
}

.cte-field input[type="text"],
.cte-field input[type="email"],
.cte-field input[type="date"],
.cte-field input[type="datetime-local"],
.cte-field select,
/* Row controls outside a .cte-field — the manual-day legs and stops, the
   reconcile-miles boxes — get the same treatment, 16px floor included. */
.cte-manual-row input,
.cte-manual-row select,
.cte-recon-row input {
  width: 100%;
  font: inherit;
  /* MUST stay at 16px or larger. Mobile Safari zooms the whole page in when a
     focused input is under 16px, and it does not zoom back out — the app then
     looks broken for the rest of the session. */
  font-size: 16px;
  min-height: var(--cte-tap);
  padding: 10px 12px;
  border: 1px solid var(--cte-line);
  border-radius: 9px;
  background: #fff;
  color: inherit;
  /* iOS otherwise applies its own inset shadow and rounding to inputs. */
  -webkit-appearance: none;
  appearance: none;
}

.cte-field input:focus,
.cte-field select:focus,
.cte-manual-row input:focus,
.cte-manual-row select:focus,
.cte-recon-row input:focus {
  outline: 2px solid rgba(47, 111, 237, 0.35);
  outline-offset: 1px;
  border-color: var(--cte-accent);
}

/* Paired fields stack on a phone and sit side by side from tablet up. */
.cte-row {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.cte-row > .cte-field { flex: 1; }

/* --- receipt scanning --------------------------------------------------- */

.cte-scan {
  margin-bottom: 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--cte-line);
}

.cte-scan-btn {
  width: 100%;
  gap: 8px;
  border-style: dashed;
  color: var(--cte-accent);
  border-color: #c3d4f7;
  background: #f7f9ff;
}

/* Stacked, camera first: photographing the receipt at the table is the common
   case, and it should be the one under the thumb. */
.cte-scan-btn + .cte-scan-btn {
  margin-top: 8px;
}

.cte-scan-combine {
  margin-top: 6px;
  font-size: 14px;
}

.cte-scan-btn svg {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
}

/* Sits where the buttons were, so the sheet does not jump as it appears. */
.cte-scan-progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
  padding: 10px 12px;
  border: 1px solid #c3d4f7;
  border-radius: 10px;
  background: #f7f9ff;
}

/* The photo just taken, so it is obvious which image is being read — and that
   the camera actually captured something. */
.cte-scan-thumb {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 8px;
  object-fit: cover;
  background: #e7ecf6;
}

.cte-scan-status {
  flex: 1;
  min-width: 0;
}

.cte-scan-stage {
  font-size: 13.5px;
  font-weight: 550;
}

.cte-scan-sub {
  font-size: 12px;
  color: var(--cte-muted);
}

.cte-spinner {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  border-radius: 50%;
  border: 2px solid #c9d8f8;
  border-top-color: var(--cte-accent);
  animation: cte-spin 0.7s linear infinite;
}

@keyframes cte-spin {
  to { transform: rotate(360deg); }
}

.cte-scan-note {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--cte-muted);
  text-align: center;
}

/* --- fleet management ---------------------------------------------------- */

.cte-unit {
  cursor: pointer;
}

.cte-fleet-add {
  display: flex;
  gap: 8px;
  margin: 8px 0 18px;
}

.cte-fleet-add input {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 16px;
  min-height: var(--cte-tap);
  padding: 10px 12px;
  border: 1px solid var(--cte-line);
  border-radius: 9px;
  -webkit-appearance: none;
  appearance: none;
}

.cte-fleet-add .cte-btn {
  flex: 0 0 auto;
}

/* --- week + receipt extras ---------------------------------------------- */

.cte-week-total {
  margin: -6px 0 14px;
  font-size: 14px;
}

.cte-mileage-hint {
  margin: -6px 0 12px;
  font-size: 12.5px;
  color: var(--cte-muted);
}

.cte-detail-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}

.cte-detail-actions .cte-btn {
  flex: 1;
}

.cte-history {
  margin-top: 4px;
}

/* --- misc --------------------------------------------------------------- */

.cte-gate {
  max-width: 380px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 0 var(--cte-gutter);
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Sized by its contents now that this is a mark plus a name, not a single
   image — the old fixed height clipped the lockup and let the name overlap the
   heading below it. */
.cte-gate-mark {
  margin: 0 auto 24px;
}

.cte-gate h2 {
  margin: 0 0 8px;
  font-size: 22px;
  letter-spacing: -0.01em;
}

.cte-gate-sub {
  margin: 0 0 24px;
  color: var(--cte-muted);
  font-size: 14.5px;
}

.cte-gate .cte-btn-lg {
  width: 100%;
}

.cte-loading {
  padding: 60px 20px;
  text-align: center;
  color: var(--cte-muted);
}

.cte-toast {
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  /* Stays inside the screen on a narrow phone instead of running off both
     edges when the message is long. */
  width: max-content;
  max-width: calc(100vw - 32px);
  background: #1d2127;
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  text-align: center;
  z-index: 10000;
  box-shadow: 0 8px 24px rgba(20, 24, 31, 0.3);
}

.cte-toast-error { background: var(--cte-negative); }

/* =========================================================================
 * Tablet and up — 600px is where two fields fit side by side comfortably.
 * ====================================================================== */

@media (min-width: 380px) {
  .cte-row {
    flex-direction: row;
    gap: 10px;
  }
}

@media (min-width: 600px) {
  :root { --cte-gutter: 18px; }

  .cte-brand img { height: 24px; }

  .cte-header-side { gap: 14px; }

  .cte-back-label,
  .cte-icon-label { display: inline; }

  .cte-icon-link svg { display: none; }

  /* Full-bleed is right under a thumb; on a wide screen it just looks heavy,
     so the button keeps its own size and centres in the bar. */
  .cte-bottom-bar-inner {
    display: flex;
    justify-content: center;
  }

  .cte-btn-lg {
    width: auto;
    min-width: 220px;
  }

  .cte-wrap { padding: 20px var(--cte-gutter) 64px; }

  .cte-section { padding: 16px 18px; }

  .cte-hero { padding: 24px; }

  /* Back to a normal inline button once there is room for it. */
  .cte-section > .cte-btn {
    display: inline-flex;
    width: auto;
  }

  .cte-trip-head {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .cte-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }

  .cte-actions .cte-btn {
    width: auto;
    min-height: 38px;
    padding: 8px 13px;
  }

  .cte-row {
    flex-direction: row;
    gap: 12px;
  }

  .cte-segmented {
    grid-template-columns: repeat(4, 1fr);
  }

  .cte-segmented button {
    border-bottom: 0;
    border-right: 1px solid var(--cte-line);
  }

  .cte-segmented button:last-child { border-right: 0; }

  .cte-compare {
    flex-direction: row;
    gap: 18px;
  }

  .cte-compare > div { flex: 1; }

  /* A centred dialog rather than a bottom sheet once the screen is big enough
     that the middle is still easy to reach. */
  .cte-overlay {
    align-items: flex-start;
    padding: 24px 12px;
    overflow-y: auto;
  }

  .cte-modal {
    max-width: 560px;
    border-radius: 14px;
    max-height: none;
    box-shadow: 0 18px 48px rgba(20, 24, 31, 0.22);
  }

  .cte-modal-body { overflow-y: visible; }

  .cte-modal-foot { justify-content: flex-end; }

  .cte-modal-foot .cte-btn { flex: 0 0 auto; }

  .cte-btn {
    min-height: 38px;
    padding: 8px 14px;
  }

  .cte-debt { flex-wrap: nowrap; }
}

/* =========================================================================
 * Desktop.
 * ====================================================================== */

@media (min-width: 900px) {
  :root { --cte-gutter: 20px; }

  .cte-header { padding: 14px 20px; }
}

/* Respect a reduced-motion preference. This has to name .cte-overlay too:
   modals are appended to <body>, so a rule scoped to .cte-app misses them —
   the same blind spot that cost the modals their box-sizing. */
@media (prefers-reduced-motion: reduce) {
  .cte-app *,
  .cte-overlay * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

  /* A frozen ring reads as broken, so the spinner becomes a plain dot and the
     stage text carries the progress on its own. */
  .cte-spinner {
    border-color: var(--cte-accent);
    border-top-color: var(--cte-accent);
    opacity: 0.5;
  }
}

/* --- status colour ------------------------------------------------------
 *
 * Three states, used by both the service alarms and the part warranties, so
 * "overdue" and "out of warranty" look like the same kind of fact — because to
 * the person reading the screen they are.
 */
.cte-alerts {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cte-alert {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 0;
  border-bottom: 1px solid var(--cte-line);
  border-left: 3px solid transparent;
  padding-left: 10px;
}

.cte-alert:last-child {
  border-bottom: 0;
}

.cte-alert > a {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  color: inherit;
  text-decoration: none;
}

.cte-alert-overdue { border-left-color: var(--cte-negative); }
.cte-alert-soon    { border-left-color: var(--cte-warn); }
.cte-alert-ok      { border-left-color: var(--cte-positive); }

/* Never recorded is not a problem, it is an absence — so it gets no colour at
   all rather than a colour that says "fine" or a colour that says "wrong". */
.cte-alert-unrecorded { border-left-color: var(--cte-line); }

.cte-alert-when {
  margin-left: auto;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.cte-alert-overdue .cte-alert-when { color: var(--cte-negative); }
.cte-alert-soon .cte-alert-when    { color: var(--cte-warn); }
.cte-alert-unrecorded .cte-alert-when { color: var(--cte-muted); font-weight: 400; }

.cte-warranty {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--cte-bg);
  color: var(--cte-muted);
}

.cte-warranty-covered  { background: rgba(18, 133, 90, 0.12);  color: var(--cte-positive); }
.cte-warranty-expiring { background: rgba(154, 91, 0, 0.12);   color: var(--cte-warn); }
.cte-warranty-expired  { background: rgba(194, 55, 75, 0.1);   color: var(--cte-negative); }

/* --- the overdue banner ------------------------------------------------- */

.cte-banner {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  margin-bottom: 14px;
  border-radius: var(--cte-radius);
  text-decoration: none;
  background: rgba(194, 55, 75, 0.09);
  border: 1px solid rgba(194, 55, 75, 0.28);
  color: var(--cte-negative);
}

.cte-banner span {
  color: var(--cte-text);
  font-size: 13px;
}

/* --- chips and filters -------------------------------------------------- */

.cte-filters {
  background: var(--cte-surface);
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
  padding: 10px 12px;
  margin-bottom: 14px;
}

.cte-filter-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
}

.cte-filter-row + .cte-filter-row {
  border-top: 1px solid var(--cte-line);
}

.cte-filter-label {
  flex: none;
  width: 74px;
  padding-top: 7px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--cte-muted);
}

.cte-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cte-chip {
  border: 1px solid var(--cte-line);
  background: var(--cte-surface);
  color: var(--cte-text);
  border-radius: 999px;
  padding: 6px 12px;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  /* Chips are the one control here deliberately below the 44px tap target:
     a row of six at full height would push the whole report off the screen.
     They are wide, well spaced, and never destructive. */
  min-height: 34px;
}

.cte-chip-on {
  background: var(--cte-accent);
  border-color: var(--cte-accent);
  color: #fff;
}

.cte-date-range {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.cte-date-range input {
  min-height: 34px;
  padding: 4px 8px;
  border: 1px solid var(--cte-line);
  border-radius: 8px;
  font: inherit;
  font-size: 14px;
  background: var(--cte-surface);
  color: var(--cte-text);
}

/* --- proportion bars ---------------------------------------------------- */

.cte-bar-row {
  gap: 8px;
}

.cte-bar {
  flex: 1 1 60px;
  height: 6px;
  min-width: 40px;
  border-radius: 3px;
  background: var(--cte-line);
  overflow: hidden;
}

.cte-bar-fill {
  display: block;
  height: 100%;
  background: var(--cte-accent);
}

/* --- rows that are links ------------------------------------------------ */

.cte-row-link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.cte-unit-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--cte-muted);
}

.cte-kind {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 5px;
  background: var(--cte-bg);
  color: var(--cte-muted);
}

.cte-kind-repair {
  background: rgba(154, 91, 0, 0.12);
  color: var(--cte-warn);
}

.cte-tag {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--cte-bg);
  color: var(--cte-muted);
  vertical-align: middle;
}

.cte-retired {
  opacity: 0.6;
}

.cte-avatars {
  display: flex;
  flex: none;
}

/* Overlapped, so four drivers on a truck still fit on a phone row. */
.cte-avatars .cte-avatar + .cte-avatar {
  margin-left: -8px;
}

.cte-has-photo {
  color: var(--cte-muted);
  font-size: 12px;
}

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

.cte-checks {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 46vh;
  overflow-y: auto;
}

.cte-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--cte-tap);
  padding: 0 4px;
  cursor: pointer;
}

.cte-check input {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--cte-accent);
}

/* --- keeping the photo -------------------------------------------------- */

.cte-photo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}

.cte-photo-kept {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--cte-line);
  border-radius: 10px;
  background: var(--cte-surface);
  font-size: 13px;
  color: var(--cte-muted);
}

.cte-photo-thumb {
  width: 38px;
  height: 38px;
  object-fit: cover;
  border-radius: 6px;
  flex: none;
}

.cte-photo-kept .cte-icon {
  margin-left: auto;
}

.cte-receipt-photo {
  display: block;
  margin: 12px 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--cte-line);
}

.cte-receipt-photo img {
  display: block;
  width: 100%;
  height: auto;
}

/* --- small buttons ------------------------------------------------------ */

.cte-btn-tiny {
  min-height: 30px;
  padding: 0 10px;
  font-size: 13px;
  float: right;
  margin-top: -3px;
}

.cte-btn-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--cte-accent);
  min-height: 32px;
  padding: 0 8px;
  font-size: 13px;
}

.cte-hero-config {
  margin-top: 6px;
}

.cte-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 6px;
  color: var(--cte-muted);
  text-decoration: none;
  font-size: 14px;
}

.cte-back svg {
  width: 16px;
  height: 16px;
}

/* The view is the scroll container now, not the page, so it carries the
   bottom-bar clearance that .cte-wrap used to own alone. */
.cte-view {
  min-height: calc(100dvh - 56px);
}

/* The pinned action is fixed to the viewport, so on a wide screen with the
   drawer pinned open it would otherwise run underneath it. It starts where the
   content starts instead. The z-index stays below the drawer's 40 so the menu
   still slides over it on a phone. */
@media (min-width: 900px) {
  body.cte-drawer-open .cte-bottom-bar {
    left: 264px;
  }

  .cte-bottom-bar {
    transition: left 0.22s ease;
  }
}

/* ---------------------------------------------------------------------------
   FUEL, MILEAGE AND IFTA
   --------------------------------------------------------------------------- */

/* A required field is marked on its label rather than with the `required`
   attribute: these forms submit by script, so the browser's own validation
   never fires and its bubble would read worse than the hint under the field. */
.cte-field.cte-required > span::after {
  content: " *";
  color: var(--cte-negative);
  font-weight: 700;
}

.cte-fuel-hint,
.cte-legs-hint {
  margin: -4px 0 10px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--cte-muted);
}

.cte-fuel-hint.cte-negative,
.cte-legs-hint.cte-negative {
  color: var(--cte-negative);
}

.cte-footnote {
  margin: 18px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--cte-muted);
}

/* --- the split panel on a scanned ticket ---------------------------------- */

.cte-split {
  margin: 10px 0 4px;
  padding: 10px 12px;
  border: 1px dashed var(--cte-line);
  border-radius: var(--cte-radius);
  background: var(--cte-bg);
}

.cte-split-head {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--cte-muted);
}

.cte-split-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cte-split-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  font-size: 14px;
}

.cte-split-name { font-weight: 600; }

.cte-split-meta {
  flex: 1;
  font-size: 12px;
  color: var(--cte-muted);
}

.cte-split-amount {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* --- legs on a trip row --------------------------------------------------- */

.cte-legs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

.cte-leg {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--cte-bg);
  color: var(--cte-text);
  font-variant-numeric: tabular-nums;
}

/* A jurisdiction outside the agreement still shows — the miles are real — but
   reads as a footnote, because it earns no row on the return. */
.cte-leg-off {
  opacity: 0.6;
  font-style: italic;
}

.cte-leg em {
  font-style: normal;
  color: var(--cte-muted);
}

/* --- the legs editor ------------------------------------------------------ */

.cte-legs-editor {
  margin: 4px 0 14px;
}

.cte-field-head {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--cte-muted);
}

.cte-leg-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  align-items: center;
}

/* The state picker earns the space: the two mileage boxes only ever hold a
   handful of digits, and on a phone the row must still fit. */
.cte-leg-row select { flex: 2 1 0; min-width: 0; }
.cte-leg-row input  { flex: 1 1 0; min-width: 0; }

.cte-leg-row select,
.cte-leg-row input {
  min-height: var(--cte-tap);
  padding: 8px 10px;
  border: 1px solid var(--cte-line);
  border-radius: 10px;
  background: var(--cte-surface);
  color: var(--cte-text);
  font: inherit;
  font-size: 16px;
}

.cte-leg-row select:focus,
.cte-leg-row input:focus {
  outline: none;
  border-color: var(--cte-accent);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15);
}

.cte-leg-drop {
  flex: 0 0 auto;
  color: var(--cte-muted);
}

.cte-legs-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.cte-legs-total {
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* --- the exceptions list -------------------------------------------------- */

.cte-problems {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cte-problem {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--cte-line);
  font-size: 14px;
  line-height: 1.45;
}

.cte-problem:last-child { border-bottom: 0; }

.cte-problem .cte-tag { flex: 0 0 auto; }

.cte-tag-blocking {
  background: rgba(194, 55, 75, 0.12);
  color: var(--cte-negative);
}

.cte-tag-warning,
.cte-tag-warn {
  background: rgba(154, 91, 0, 0.12);
  color: var(--cte-warn);
}

.cte-tag-note {
  background: var(--cte-bg);
  color: var(--cte-muted);
}

/* --- the jurisdiction table ----------------------------------------------- */

/* The table is six numeric columns wide and will not fit a phone, so it scrolls
   inside its own box rather than making the whole page scroll sideways. */
.cte-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 calc(var(--cte-gutter) * -1);
  padding: 0 var(--cte-gutter);
}

.cte-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cte-table th,
.cte-table td {
  padding: 8px 10px;
  text-align: right;
  border-bottom: 1px solid var(--cte-line);
}

.cte-table thead th {
  font-size: 12px;
  font-weight: 600;
  color: var(--cte-muted);
  text-align: right;
  white-space: normal;
}

/* The jurisdiction column is the row's label, so it anchors left and stays put
   while the numbers scroll under the reader's thumb. */
.cte-table th[scope="row"],
.cte-table thead th:first-child {
  text-align: left;
  position: sticky;
  left: 0;
  background: var(--cte-surface);
}

.cte-juris-name {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: var(--cte-muted);
}

.cte-row-off td,
.cte-row-off th {
  opacity: 0.65;
}

.cte-table .cte-positive { color: var(--cte-positive); font-weight: 600; }
.cte-table .cte-negative { color: var(--cte-negative); font-weight: 600; }

.cte-ifta-totals {
  margin-bottom: 4px;
}

/* --- trips: a truck's week from its ELD logs ------------------------------ */

.cte-run-days {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

.cte-run-day {
  padding: 12px var(--cte-gutter);
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
  background: var(--cte-surface);
}

.cte-run-day-empty {
  background: transparent;
  border-style: dashed;
}

.cte-run-day-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
}

.cte-run-day-head h3 {
  margin: 0;
  flex: 1;
  font-size: 15px;
}

.cte-run-odo {
  font-variant-numeric: tabular-nums;
  color: var(--cte-muted);
  font-size: 13px;
}

.cte-run-miles {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cte-run-states {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin: 8px 0 4px;
}

.cte-run-arrow {
  color: var(--cte-muted);
  font-size: 12px;
}

.cte-run-warning {
  display: block;
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--cte-warn);
}

.cte-run-receipts {
  margin-top: 8px;
}

.cte-run-events {
  margin-top: 8px;
  font-size: 13px;
}

.cte-run-events summary {
  cursor: pointer;
  color: var(--cte-accent);
  min-height: 32px;
  line-height: 32px;
}

.cte-run-events ol {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.cte-run-events li {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 8px;
  padding: 3px 0;
  border-top: 1px solid var(--cte-line);
}

.cte-run-event-time,
.cte-run-event-odo {
  font-variant-numeric: tabular-nums;
  color: var(--cte-muted);
}

.cte-run-admin {
  margin: 18px 0 0;
  text-align: center;
}

.cte-run-stops {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.cte-run-stop {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--cte-line);
}

.cte-run-stop-kind {
  flex: none;
  min-width: 78px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.cte-run-stop-pickup .cte-run-stop-kind { color: var(--cte-accent); }
.cte-run-stop-delivery .cte-run-stop-kind { color: var(--cte-positive); }

.cte-run-stop-where {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  font-size: 14px;
}

.cte-run-map {
  flex: none;
  min-height: 34px;
  padding: 0 12px;
  font-size: 13px;
}

.cte-run-stop-fuel .cte-run-stop-kind { color: var(--cte-warn); }

.cte-run-stop-marked {
  display: block;
  font-size: 10px;
  font-weight: 600;
  color: var(--cte-muted);
  text-transform: none;
  letter-spacing: 0;
}

.cte-run-mark {
  margin-left: 6px;
  padding: 2px 8px;
  min-height: 26px;
  border: 1px solid var(--cte-line);
  border-radius: 6px;
  background: var(--cte-surface);
  color: var(--cte-accent);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.cte-run-mark-pickup { color: var(--cte-accent); border-color: currentColor; }
.cte-run-mark-delivery { color: var(--cte-positive); border-color: currentColor; }
.cte-run-mark-fuel { color: var(--cte-warn); border-color: currentColor; }

.cte-run-event-stale {
  opacity: 0.55;
  text-decoration: line-through;
  text-align: right;
}

.cte-run-event-stale small {
  display: block;
  font-size: 10px;
  text-decoration: none;
}

.cte-run-carryover {
  display: block;
  font-size: 11px;
  color: var(--cte-muted);
}

.cte-run-stop {
  flex-wrap: wrap;
}

.cte-run-stop-actions {
  display: flex;
  gap: 6px;
  flex: none;
}

.cte-stop-docs {
  flex-basis: 100%;
  margin: 2px 0 0 88px;
  padding: 0;
  list-style: none;
  font-size: 13px;
}

.cte-stop-docs li {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 30px;
}

.cte-stop-docs a {
  color: var(--cte-accent);
  overflow-wrap: anywhere;
}

.cte-stop-doc-delete {
  margin-left: auto;
  width: 30px;
  height: 30px;
  border: 0;
  background: transparent;
  color: var(--cte-muted);
  font-size: 18px;
  cursor: pointer;
}

.cte-run-other-docs {
  margin-top: 8px;
}

.cte-run-other-docs .cte-stop-docs {
  margin-left: 0;
}

@media (max-width: 480px) {
  .cte-stop-docs { margin-left: 0; }
}

.cte-run-state-miles {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 4px 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--cte-muted);
}

.cte-run-state-miles b {
  color: var(--cte-text);
}

.cte-fuel-check {
  margin: 10px 0 4px;
  font-size: 14px;
  font-weight: 600;
}

.cte-fuel-check.cte-positive { color: var(--cte-positive); }
.cte-fuel-check.cte-negative { color: var(--cte-warn); }

/* --- reconciled miles on the IFTA return ----------------------------------- */

.cte-recon-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
  font-weight: 600;
  font-size: 14px;
}

.cte-recon-bar .cte-positive { color: var(--cte-positive); }
.cte-recon-bar .cte-negative { color: var(--cte-warn); }

.cte-recon-miles {
  color: var(--cte-positive);
  font-weight: 700;
}

.cte-recon-open {
  color: var(--cte-muted);
}

.cte-recon-est {
  display: block;
  font-size: 11px;
  color: var(--cte-muted);
  font-weight: 400;
}

.cte-recon-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 8px 0;
}

.cte-recon-row {
  display: grid;
  grid-template-columns: 1fr auto 96px;
  align-items: center;
  gap: 10px;
}

.cte-recon-state {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cte-recon-row input {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.cte-recon-row input::placeholder {
  color: var(--cte-muted);
  opacity: 0.5;
}

.cte-recon-total {
  margin: 6px 0 0;
  font-weight: 600;
  font-size: 13px;
}

/* Fuel receipts folded into their fueling stop: a tinted panel with the
   fueling colour down its edge, so it reads as part of the stop above it and
   not as the next item in the day. */
.cte-stop-receipts {
  flex-basis: 100%;
  margin: 6px 0 2px 88px;
  padding: 2px 10px;
  border-left: 3px solid var(--cte-warn);
  border-radius: 0 8px 8px 0;
  background: var(--cte-bg);
}

.cte-stop-receipts > li + li {
  border-top: 1px solid var(--cte-line);
}

.cte-stop-note {
  flex-basis: 100%;
  margin-left: 88px;
}

@media (max-width: 480px) {
  .cte-stop-receipts,
  .cte-stop-note { margin-left: 12px; }
}

/* --- duplicate receipts ----------------------------------------------------- */

.cte-banner-warn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px var(--cte-gutter);
  background: #fff4e0;
  border-bottom: 1px solid #f0d6a8;
  color: var(--cte-warn);
  font-size: 14px;
  font-weight: 600;
}

.cte-banner-warn .cte-btn {
  flex: none;
  min-height: 34px;
}

.cte-dup-lead {
  margin: 0 0 10px;
}

.cte-dup-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}

.cte-dup-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--cte-line);
  border-radius: var(--cte-radius);
}

.cte-dup-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 8px;
}

.cte-dup-photo {
  width: 100%;
  max-height: 220px;
  object-fit: contain;
  border-radius: 8px;
  background: var(--cte-bg);
}

.cte-dup-nophoto {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80px;
  color: var(--cte-muted);
  font-size: 13px;
}

.cte-dup-summary {
  margin: 0;
  font-size: 13px;
}

.cte-dup-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: auto;
}

.cte-dup-footer {
  margin: 12px 0 0;
  text-align: center;
}

/* --- trip days entered by hand ----------------------------------------------- */

.cte-tag-manual {
  font-size: 11px;
  vertical-align: middle;
}

.cte-run-day-tools {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}

.cte-manual-legs,
.cte-manual-stops {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 6px 0;
}

.cte-manual-row {
  display: grid;
  grid-template-columns: 1fr 100px 30px;
  gap: 8px;
  align-items: center;
}

.cte-manual-stop {
  grid-template-columns: 112px 1fr 96px 30px;
}

@media (max-width: 480px) {
  /* Too narrow for four controls in a row: kind and time on one line,
     location on its own below. */
  .cte-manual-stop {
    grid-template-columns: 1fr 96px 30px;
  }

  .cte-manual-stop [name="stop_location"] {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}

.cte-manual-row input {
  min-width: 0;
}

/* Two actions in the pinned bar: side by side, the primary one first. */
.cte-bottom-bar-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.cte-bottom-bar-split .cte-btn-lg {
  padding-left: 8px;
  padding-right: 8px;
}

/* --- a day's route with its miles, as one bar ------------------------------ */

.cte-route-bar {
  display: flex;
  gap: 2px;
  margin: 8px 0 4px;
  border-radius: 8px;
  overflow: hidden;
}

.cte-route-seg {
  flex: 1 1 0;
  min-width: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 5px 4px;
  font-size: 12px;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
}

.cte-route-seg b { font-size: 13px; }

.cte-route-c0 { background: #e2d6df; color: #482b41; }
.cte-route-c1 { background: #e9eac2; color: #4a4b0e; }
.cte-route-c2 { background: #d4e4f7; color: #1d4a80; }
.cte-route-c3 { background: #d5eee2; color: #0d5c3d; }
.cte-route-c4 { background: #f6e0c8; color: #7a4300; }
.cte-route-c5 { background: #eadcf5; color: #55307a; }

/* Worth knowing, not a problem: Personal Conveyance miles and the like. */
.cte-run-info {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--cte-muted);
}

/* --- data checks ------------------------------------------------------------ */

.cte-findings {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
}

.cte-finding {
  padding: 10px 0;
  border-top: 1px solid var(--cte-line);
}

.cte-finding-text {
  margin: 0 0 8px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.cte-finding-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cte-finding-tools .cte-btn {
  min-height: 36px;
}
