/* Upload Portal — the look.
 *
 * Built for one reader: a photographer holding a phone, one-handed, either in a driveway in
 * midday sun or in a car at 8pm. Everything here follows from that.
 *
 *   · Light by day, dark by night — the theme follows the phone, and BOTH are designed. A dark
 *     UI in direct sunlight is unreadable, which is why light is no longer an afterthought.
 *   · Thumb reach. The thing you press to finish a job lives at the BOTTOM of the screen, and so
 *     does the navigation. The top of a 6.7" phone is not somewhere a thumb goes.
 *   · One primary action per screen, in the brand blue. If two things are blue, neither is the
 *     next thing to do.
 *   · 16px inputs, always — anything smaller makes iOS zoom on focus and never zoom back.
 *   · Safe-area insets, so the notch doesn't eat the header and the home indicator doesn't sit
 *     on top of the Complete Job button.
 *
 * The palette is Vision Real Estate Media's own: the near-black #0c0c0e the site is built on,
 * its blue #2f6fe0, and neutral greys with no colour cast. Same tokens as the website, so the
 * portal and the brand look like they came from the same place.
 */

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: light;

  /* Brand constants — the same in both themes, because a brand that changes colour isn't one. */
  --brand-ink: #0c0c0e;
  --brand-ink-2: #1c1c22;
  --accent: #2f6fe0;
  --accent-strong: #1e4fc4;
  --accent-on: #ffffff;

  /* Surfaces */
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #f7f8fa;
  --surface-3: #eceef2;
  --line: #e3e5ea;
  --line-strong: #d3d7df;

  /* Text */
  --txt: #14151a;
  --txt-2: #4b515e;
  --dim: #7b8290;

  /* Status */
  --ok: #128a52;
  --ok-bg: #e7f6ee;
  --warn: #a2620a;
  --warn-bg: #fdf2df;
  --bad: #c8253c;
  --bad-bg: #fdecef;
  --accent-bg: #e9f0fd;

  /* The RAW-folder button. Brand black on a light page; on a dark page black-on-black is
     invisible, so it becomes the lightest neutral surface instead. */
  --folder-bg: var(--brand-ink);
  --folder-bg-hover: var(--brand-ink-2);
  --folder-fg: #ffffff;
  --folder-line: transparent;

  /* Shape + depth */
  --r-sm: 10px;
  --r: 14px;
  --r-lg: 20px;
  --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(12, 12, 14, .05), 0 1px 3px rgba(12, 12, 14, .04);
  --shadow-2: 0 2px 4px rgba(12, 12, 14, .05), 0 8px 24px rgba(12, 12, 14, .07);
  --shadow-up: 0 -1px 0 var(--line), 0 -8px 24px rgba(12, 12, 14, .06);
  --ring: 0 0 0 3px rgba(47, 111, 224, .22);

  /* Chrome heights, kept as variables so the sticky action bar can sit exactly on top of the
     navigation bar rather than guessing at it. */
  --appbar-h: 56px;
  --tabbar-h: 60px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-display: "Sora", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --bg: #0c0c0e;
    --surface: #17181c;
    --surface-2: #1e2026;
    --surface-3: #262931;
    --line: #2a2d35;
    --line-strong: #3a3e49;

    --txt: #eceef2;
    --txt-2: #b3b9c5;
    --dim: #868d9b;

    --accent: #5a8ce8;
    --accent-strong: #7aa5f0;
    --accent-on: #08131f;

    --ok: #4ade9a;
    --ok-bg: rgba(74, 222, 154, .12);
    --warn: #f2b455;
    --warn-bg: rgba(242, 180, 85, .13);
    --bad: #ff7a90;
    --bad-bg: rgba(255, 122, 144, .12);
    --accent-bg: rgba(90, 140, 232, .14);

    --folder-bg: var(--surface-3);
    --folder-bg-hover: #30343d;
    --folder-fg: var(--txt);
    --folder-line: var(--line-strong);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, .45), 0 12px 32px rgba(0, 0, 0, .35);
    --shadow-up: 0 -1px 0 var(--line), 0 -10px 28px rgba(0, 0, 0, .45);
    --ring: 0 0 0 3px rgba(90, 140, 232, .3);
  }
}

/* ------------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--txt);
  font: 16px/1.55 var(--font);
  font-feature-settings: "cv05", "ss01";
  letter-spacing: -.005em;
  padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom));
}
/* The sign-in screen has no navigation to leave room for. */
body.signedout { padding-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

svg.i { width: 1em; height: 1em; flex: none; display: block; }

/* --------------------------------------------------------------- app bar */

/* Brand black in both themes. It is the one piece of the page that is always Vision's colour,
   and it gives the phone's status bar something solid to sit against. */
.appbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 12px;
  height: calc(var(--appbar-h) + var(--safe-top));
  padding: var(--safe-top) 16px 0;
  background: var(--brand-ink);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.appbar .logo { display: flex; align-items: center; gap: 10px; margin-right: auto; min-width: 0; }
.appbar .logo:hover { text-decoration: none; }
.appbar .logo img { height: 21px; width: auto; display: block; }
.appbar .logo .what {
  color: rgba(255, 255, 255, .5);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  padding-left: 10px;
  border-left: 1px solid rgba(255, 255, 255, .18);
  white-space: nowrap;
}
@media (max-width: 359px) { .appbar .logo .what { display: none; } }

/* The signed-in photographer, as initials. Their own name in full is on the Account page; up
   here it only has to answer "am I logged in as me?". */
.appbar .me {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .16);
  color: #fff;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: .02em;
}
.appbar .me:hover { text-decoration: none; background: rgba(255, 255, 255, .18); }
.appbar form.inline { display: flex; }
.appbar .signout {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: none;
  background: none;
  color: rgba(255, 255, 255, .5);
  padding: 0;
  cursor: pointer;
}
.appbar .signout svg.i { width: 19px; height: 19px; }
.appbar .signout:hover { color: #fff; }

/* --------------------------------------------------------- bottom tab bar */

/* Navigation a thumb can reach. The old version was seven blue links wrapping onto two rows at
   the top of the screen — the least reachable pixels on the phone, and nothing said which page
   you were on. */
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  height: calc(var(--tabbar-h) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  /* The solid colour first: color-mix arrived in Safari 16.4, and an older iPhone that skips
     the second line gets an opaque bar rather than a transparent one. */
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  box-shadow: var(--shadow-up);
}
.tabbar a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--dim);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  padding-top: 2px;
}
.tabbar a:hover { text-decoration: none; color: var(--txt-2); }
.tabbar a svg.i { width: 22px; height: 22px; }
.tabbar a.on { color: var(--accent); }
/* The current page gets a mark above the icon as well as the colour — colour alone is a poor
   signal in bright sun. */
.tabbar a.on::before {
  content: "";
  position: absolute;
  top: 0;
  width: 26px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--accent);
}
.tabbar a { position: relative; }
/* On a laptop the bar still spans the window — it is the same navigation — but the items gather
   in the middle over the content rather than stretching to the corners of a 27" screen. */
@media (min-width: 760px) {
  .tabbar { justify-content: center; }
  .tabbar a { flex: 0 1 130px; }
}

/* ---------------------------------------------------------------- layout */

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 18px 16px 28px;
}
@media (min-width: 760px) { .wrap { padding: 26px 24px 40px; } }

h1 {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: 2px 0 14px;
}
h2 {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -.01em;
  margin: 26px 0 10px;
}
p { margin: 0 0 12px; }
.sub { color: var(--dim); font-size: 13.5px; }
.sub.lede { margin: -10px 0 16px; font-size: 14.5px; color: var(--txt-2); }
.sub.lede b { color: var(--txt); font-weight: 650; }
.hint { font-size: 12.5px; color: var(--dim); margin-top: 6px; }
.hint.ok { color: var(--ok); }
.hint.bad { color: var(--bad); font-weight: 550; }

/* A way back that doesn't depend on browser history. */
.back { margin: 0 0 10px; font-size: 14px; font-weight: 550; }
.back a { display: inline-flex; align-items: center; gap: 6px; color: var(--txt-2); }
.back a:hover { color: var(--accent); text-decoration: none; }

/* --------------------------------------------------------------- notices */

.notice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  border: 1px solid var(--line);
  border-left: 4px solid var(--ok);
  background: var(--surface);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  margin: 0 0 16px;
  font-size: 14.5px;
  box-shadow: var(--shadow-1);
}
.notice.bad { border-left-color: var(--bad); background: var(--bad-bg); border-color: transparent; }
.notice.warn { border-left-color: var(--warn); background: var(--warn-bg); border-color: transparent; }

/* A refused submit, said plainly and first. */
.refused {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bad-bg);
  color: var(--bad);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-weight: 620;
  font-size: 14.5px;
  margin: 0 0 16px;
}

.empty {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 40px 24px;
  text-align: center;
  box-shadow: var(--shadow-1);
}
.empty svg.i { width: 34px; height: 34px; margin: 0 auto 12px; color: var(--dim); opacity: .7; }
.empty p { margin: 0 0 6px; font-weight: 550; }
.empty .sub { font-weight: 400; }

/* --------------------------------------------------------------- controls */

input, select, button, textarea { font: inherit; font-size: 16px; }

input, select, textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--txt);
  transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { resize: vertical; min-height: 84px; line-height: 1.5; }
input::placeholder, textarea::placeholder { color: var(--dim); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ring);
}
/* The native select arrow is a different shape and weight in every browser, and on macOS it is a
   heavy black triangle that reads as the loudest thing on a quiet form. Drawn here instead. */
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--dim) 50%),
    linear-gradient(135deg, var(--dim) 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% - 2px), calc(100% - 14px) calc(50% - 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 40px;
}
select[multiple] {
  -webkit-appearance: none;
  min-height: 170px;
  background-image: none;
  padding-right: 14px;
}

button {
  font-weight: 620;
  padding: 12px 18px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--txt);
  cursor: pointer;
  transition: transform .08s ease, background .12s ease, border-color .12s ease;
}
button:hover { border-color: var(--dim); }
button:active { transform: scale(.985); }
/* The one blue button on a screen is the next thing to do. */
button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
  box-shadow: 0 1px 2px rgba(30, 79, 196, .3);
}
button.primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
button.link {
  background: none;
  border: none;
  color: var(--accent);
  padding: 0;
  font-weight: 550;
  font-size: 14px;
  cursor: pointer;
}
button.link:hover { text-decoration: underline; }

a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  font-weight: 620;
  padding: 12px 18px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--txt);
}
a.btn:hover { text-decoration: none; border-color: var(--dim); }
a.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-on); }

form.stack, .gate form { display: flex; flex-direction: column; gap: 12px; max-width: 420px; }
form.inline { display: inline; }
form.signout-row { margin-top: 28px; }
form.signout-row button { display: flex; align-items: center; justify-content: center; gap: 9px; }
form.signout-row svg.i { width: 17px; height: 17px; }

label.field { display: block; margin-top: 16px; }
label.field .lbl,
.note .lbl,
.ticks .lbl {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--dim);
  margin-bottom: 6px;
  font-weight: 700;
}

/* A checkbox is a row you can hit anywhere, not a 20px square you have to aim at. */
label.check {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  cursor: pointer;
  font-size: 15px;
  font-weight: 550;
  transition: border-color .12s ease, background .12s ease;
}
label.check:hover { border-color: var(--line-strong); }
label.check:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-bg);
}
label.check input { width: 22px; height: 22px; flex: none; accent-color: var(--accent); margin: 0; }

/* A box with a problem says so where it is. */
input.wrong, textarea.wrong {
  border-color: var(--bad);
  background: var(--bad-bg);
}
input.wrong:focus, textarea.wrong:focus {
  border-color: var(--bad);
  box-shadow: 0 0 0 3px rgba(200, 37, 60, .18);
}

/* ------------------------------------------------------------------ gate */

.gate {
  max-width: 380px;
  margin: 8vh auto 0;
  text-align: center;
}
.gate .gate-logo { height: 34px; width: auto; margin: 0 auto 22px; display: block; }
.gate h1 { font-size: 21px; margin-bottom: 4px; }
.gate .sub { margin-bottom: 24px; }
.gate form { text-align: left; margin: 0 auto; }
.gate .notice { text-align: left; }

/* --------------------------------------------------------- segmented tabs */

/* Which slice of the job list you are looking at. A segmented control, because the three are
   alternatives to each other — the old row of separate pills read like five equal buttons with
   two unrelated "+" ones mixed in. */
.tabs {
  display: flex;
  gap: 4px;
  margin: 0 0 14px;
  padding: 4px;
  background: var(--surface-3);
  border-radius: var(--r-pill);
}
.tab {
  flex: 1;
  text-align: center;
  padding: 8px 10px;
  border-radius: var(--r-pill);
  color: var(--txt-2);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}
.tab:hover { text-decoration: none; color: var(--txt); }
.tab.on {
  background: var(--surface);
  color: var(--txt);
  box-shadow: var(--shadow-1);
}

/* A password shown exactly once. Big, monospaced and selectable, because it gets read aloud or
   copied — a proportional font makes 1/l and 0/O a coin toss at the worst possible moment. */
.onetime {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .04em;
  margin: 8px 0 6px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  user-select: all;
  -webkit-user-select: all;
  overflow-wrap: anywhere;
}

.tabs.pager { background: none; padding: 0; margin-top: 18px; }
.tabs.pager .tab {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  flex: none;
  margin: 0 auto;
  padding: 10px 22px;
}

form.search { display: flex; gap: 8px; margin: 0 0 18px; max-width: none; }
form.search input { flex: 1; min-width: 0; }
form.search button { flex: none; }

/* ------------------------------------------------------------- job cards */

a.card {
  position: relative;
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 15px 40px 15px 17px;
  margin-bottom: 11px;
  color: var(--txt);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform .1s ease, box-shadow .14s ease, border-color .14s ease;
}
a.card:hover {
  text-decoration: none;
  border-color: var(--line-strong);
  box-shadow: var(--shadow-2);
  transform: translateY(-1px);
}
a.card:active { transform: translateY(0); }
/* A colour rail down the left edge: blue means someone still has to finish it, green means it
   has gone. Readable at a glance down a list of twenty. */
a.card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--accent);
}
a.card[data-status="submitted"]::before { background: var(--ok); }
/* The chevron says the whole card is the target, so nobody hunts for a link inside it. */
a.card::after {
  content: "";
  position: absolute;
  right: 17px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -5px;
  border-right: 2px solid var(--dim);
  border-bottom: 2px solid var(--dim);
  transform: rotate(-45deg);
  opacity: .7;
}

.chead { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 7px; }
.addr {
  font-family: var(--font-display);
  font-size: 16.5px;
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: -.02em;
  flex: 1;
}
.cmeta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  color: var(--dim);
  font-size: 13px;
  font-weight: 500;
}
.cmeta span { display: inline-flex; align-items: center; gap: 5px; }
.cmeta svg.i { width: 14px; height: 14px; opacity: .85; }

/* Services as chips, not a comma-run. Four services in prose is a sentence to read; four chips
   is a shape to recognise. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.chip {
  font-size: 12px;
  font-weight: 570;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  color: var(--txt-2);
  white-space: nowrap;
}
.chip.none { background: transparent; border: 1px dashed var(--line-strong); color: var(--dim); }
.chip.more { background: transparent; border: 1px solid var(--line-strong); color: var(--dim); }

/* --------------------------------------------------------------- badges */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-weight: 750;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  background: var(--surface-3);
  color: var(--dim);
}
.badge.submitted { background: var(--ok-bg); color: var(--ok); }
.badge.ready { background: var(--accent-bg); color: var(--accent); }
.statusline { margin: -6px 0 16px; display: flex; gap: 8px; flex-wrap: wrap; }

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

/* Everything about the shoot, above the boxes to fill in: where, when, who, and the one link
   that gets pressed on every single job. */
.jobhead {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px 18px;
  margin: 0 0 16px;
  box-shadow: var(--shadow-1);
}
.jobhead h1 { margin: 0 0 10px; font-size: 24px; }
.jobhead .statusline { margin: 0 0 14px; }

/* The RAW folder, as a button rather than a line of blue text in a list. It is the most-pressed
   thing on the page and it used to look like every other fact on it. */
.folderlink {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 13px 15px;
  margin: 0 0 14px;
  border-radius: var(--r-sm);
  background: var(--folder-bg);
  border: 1px solid var(--folder-line);
  color: var(--folder-fg);
  font-weight: 620;
  font-size: 15px;
}
.folderlink:hover { text-decoration: none; background: var(--folder-bg-hover); }
.folderlink svg.i { width: 19px; height: 19px; }
.folderlink .go { margin-left: auto; opacity: .6; font-size: 13px; font-weight: 500; }
.folderlink.off {
  background: var(--surface-2);
  color: var(--dim);
  border: 1px dashed var(--line-strong);
  font-weight: 550;
  font-size: 14px;
}

dl.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 9px 18px;
  margin: 0;
  font-size: 14.5px;
}
dl.facts dt { color: var(--dim); font-size: 13px; font-weight: 550; }
dl.facts dd { margin: 0; }
dl.facts dd .chips { margin-top: -1px; }
dl.facts dt { padding-top: 1px; }
dl.facts dd a { word-break: break-word; }
/* Standalone fact lists — the account page, the reshoot picker — still want their own box. */
dl.facts.boxed {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 16px 18px;
  box-shadow: var(--shadow-1);
}

/* --------------------------------------------------------------- panels */

section.block {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 16px 18px 20px;
  margin-top: 14px;
  box-shadow: var(--shadow-1);
}
section.block h2 {
  margin: 0 0 4px;
  font-size: 16px;
  font-weight: 680;
}
section.block > .sub { margin-bottom: 14px; }
section.block > label.field:first-of-type { margin-top: 12px; }
/* A section holding a problem is outlined, so scrolling past it is hard. */
section.block.wrong {
  border-color: var(--bad);
  box-shadow: 0 0 0 1px var(--bad), var(--shadow-1);
}

.note {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  margin-top: 12px;
  font-size: 14.5px;
  white-space: pre-wrap;
}

/* How many the order says. */
p.ordered {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  margin: 2px 0 12px;
  padding: 4px 11px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  color: var(--txt-2);
}
p.ordered b { color: var(--txt); }
p.ordered.ok { background: var(--ok-bg); color: var(--ok); }
p.ordered.ok b { color: var(--ok); }

.verdict { font-weight: 640; font-size: 14px; color: var(--ok); padding: 11px 0; }

/* A submitted job still shows everything that was entered — it just can't be changed. */
.readonly input, .readonly textarea { opacity: .75; }

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

ul.checks { list-style: none; margin: 0; padding: 0; }
ul.checks li.ck {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14.5px;
  line-height: 1.45;
}
ul.checks li.ck:last-child { border-bottom: none; }
ul.checks li.ck:first-child { padding-top: 4px; }
ul.checks .mark {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 800;
  background: var(--surface-3);
  color: var(--dim);
}
li.ck.pass .mark { background: var(--ok-bg); color: var(--ok); }
li.ck.warn .mark { background: var(--warn-bg); color: var(--warn); }
li.ck.fail .mark { background: var(--bad-bg); color: var(--bad); }
li.ck.fail b { color: var(--bad); }

/* --------------------------------------------------------- photo marking */

.photo {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.photo:last-of-type { border-bottom: none; }
.photo .fname {
  font-size: 12.5px;
  color: var(--txt-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  margin-bottom: 8px;
  word-break: break-all;
}
.photo label.check { margin-top: 8px; }
.photo .drop { margin-top: 8px; font-size: 13px; color: var(--bad); }
select.photopick { margin-top: 12px; }
.picked:empty { display: none; }
.picked { margin-top: 6px; }

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

/* The finishing button, pinned above the navigation. On a long job page the old version was
   somewhere below the fold and people scrolled looking for it. */
.acts {
  position: sticky;
  bottom: calc(var(--tabbar-h) + var(--safe-bottom));
  z-index: 30;
  display: flex;
  gap: 10px;
  margin: 20px -16px 0;
  padding: 12px 16px;
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-top: 1px solid var(--line);
}
.acts button, .acts a.btn { flex: 1; min-width: 0; }
.acts button.primary { flex: 2; }
@media (min-width: 760px) { .acts { margin-left: -24px; margin-right: -24px; padding: 12px 24px; } }

/* A plain, non-sticky row — used where the buttons aren't the point of the page. */
.acts.plain {
  position: static;
  margin: 20px 0 0;
  padding: 0;
  background: none;
  border: none;
  backdrop-filter: none;
}

/* ---------------------------------------------------------------- tables */

/* A table is the wrong shape for a 375px screen, so it scrolls inside its own box rather than
   making the whole page scroll sideways. */
table.grid {
  width: 100%;
  border-collapse: collapse;
  display: block;
  overflow-x: auto;
  white-space: nowrap;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
}
table.grid th, table.grid td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  font-size: 14.5px;
  vertical-align: top;
}
table.grid tr:last-child td { border-bottom: none; }
table.grid th {
  color: var(--dim);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .07em;
  font-weight: 700;
  background: var(--surface-2);
}
table.grid tr.inactive td { opacity: .5; }
table.grid td .sub { white-space: normal; }

pre.raw {
  margin: 0;
  padding: 13px 15px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: 12.5px;
  line-height: 1.55;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 380px;
  color: var(--txt-2);
}

/* -------------------------------------------------------- editing an order */

.svc {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 8px;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.svc:last-child { border-bottom: none; }
.svc label.check { flex: 1; margin-top: 0; }
/* Name and Remove share a line; it is the "How many" box that wraps underneath when the name is
   long, because that is the part with room to spare. */
.svc-name { flex: 1 1 auto; min-width: 40%; font-weight: 550; }
.svc .drop-svc { margin-left: auto; color: var(--bad); }
.svc.removed .svc-name { text-decoration: line-through; opacity: .5; }
.svc.added .svc-name::after {
  content: "new";
  margin-left: 8px;
  font-size: 10.5px;
  font-weight: 750;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-bg);
  padding: 2px 7px;
  border-radius: var(--r-pill);
}
.qty-lbl { color: var(--dim); font-size: 13px; flex: none; }
input.qty, select.qty { width: 92px; flex: none; }
#addsvc { margin-top: 12px; align-self: flex-start; }

/* Reshoot picker */
#chosen section.block { margin-top: 12px; }
#chosen .chead { margin-bottom: 0; }
.ticks { margin: 6px 0; }

/* --------------------------------------------------------------- motion */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
