:root {
  --brand: #0e4d7d;
  --brand-dark: #0a3a5e;
  --brand-darker: #072b46;
  --brand-tint: #eaf3f9;
  --accent: #e07a2f;
  --accent-dark: #c4661f;
  --ink: #10202e;
  --body: #46586a;
  --muted: #6d7e8e;
  --line: #dce6ee;
  --bg: #ffffff;
  --bg-alt: #f5f9fc;
  --accent-tint: #fdf2e9;
  /* The green this site already says "done" in — the track marks, the active
     badge, the safe-area line. Named here because a button uses it now. */
  --go: #1e6236;
  --go-dark: #17512c;
  --radius: 12px;
  --radius-lg: 18px;
  --shadow: 0 1px 2px rgba(16, 32, 46, .06), 0 8px 24px rgba(16, 32, 46, .06);
  --shadow-sm: 0 1px 2px rgba(16, 32, 46, .05), 0 2px 8px rgba(16, 32, 46, .04);
  --shadow-lg: 0 2px 4px rgba(16, 32, 46, .05), 0 18px 44px rgba(16, 32, 46, .12);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.65;
  color: var(--body);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { color: var(--ink); line-height: 1.18; margin: 0 0 .5em; letter-spacing: -.022em; }
h1 { letter-spacing: -.032em; }
h1 { font-size: clamp(2rem, 4.2vw, 3.1rem); }
h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
h3 { font-size: 1.08rem; letter-spacing: -.01em; }
p { margin: 0 0 1rem; text-wrap: pretty; }
a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-dark); }
img, svg { max-width: 100%; }
hr { border: 0; border-top: 1px solid var(--line); margin: 1.5rem 0; }

.wrap { width: 100%; max-width: 1140px; margin: 0 auto; padding: 0 24px; }
.muted { color: var(--muted); }
.small { font-size: .875rem; }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .9em; }
.prewrap { white-space: pre-wrap; }

.eyebrow {
  text-transform: uppercase;
  letter-spacing: .13em;
  font-size: .75rem;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 .75rem;
}

/* ---------- header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: saturate(160%) blur(8px);
  border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: 72px; }
.brand { display: inline-flex; align-items: center; gap: 12px; color: var(--brand); text-decoration: none; }
.brand-image { line-height: 0; }
.brand-logo-image { display: block; width: 100%; height: auto; flex: none; object-fit: contain; }
.logo-mark { width: 34px; height: 34px; flex: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.brand-text strong { color: var(--ink); font-size: 1.02rem; letter-spacing: -.02em; }
.brand-text em { font-style: normal; font-size: .76rem; color: var(--muted); }
.site-nav { display: flex; align-items: center; gap: 26px; }
.site-nav a { color: var(--ink); text-decoration: none; font-size: .94rem; font-weight: 500; }
.site-nav a:hover { color: var(--brand); }
.site-nav .btn-accent { color: #fff; }
.inline-form { display: inline; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 24px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 600;
  font-size: .95rem;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, transform .05s ease;
}
.btn:active { transform: translateY(1px); }
.btn-sm { padding: 8px 15px; font-size: .875rem; }
.btn-block { width: 100%; }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-dark); color: #fff; }
.btn-outline { background: transparent; color: var(--brand); border-color: var(--line); }
.btn-outline:hover { border-color: var(--brand); background: var(--brand-tint); }
/* Go: the step a form cannot be finished without. Used on the artwork button,
   which is not optional however much an outline made it look it. */
.btn-go { background: var(--go); color: #fff; border-color: var(--go); }
.btn-go:hover { background: var(--go-dark); border-color: var(--go-dark); color: #fff; }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { background: var(--bg-alt); }
.btn-ghost-light { background: rgba(255, 255, 255, .1); color: #fff; border-color: rgba(255, 255, 255, .3); }
.btn-ghost-light:hover { background: rgba(255, 255, 255, .18); color: #fff; }

/* ---------- hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(820px 460px at 88% -12%, rgba(224, 122, 47, .3), transparent 60%),
    radial-gradient(900px 520px at 6% 116%, rgba(64, 156, 214, .38), transparent 62%),
    linear-gradient(158deg, #05243c 0%, var(--brand-darker) 48%, var(--brand) 100%);
  color: #dce9f3;
  padding: clamp(56px, 8vw, 104px) 0 clamp(56px, 8vw, 96px);
}
/* Faint press-sheet grid, kept behind the content. */
.hero::before {
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(120% 90% at 30% 0%, #000 20%, transparent 75%);
}
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}
.hero-inner { max-width: 620px; }
.hero h1 { text-wrap: balance; }
.hero h1 { color: #fff; margin-bottom: .45em; }
.lede { font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.62; }
.hero .lede { color: #c8dced; max-width: 62ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 2rem; }
.hero-points { display: flex; flex-wrap: wrap; gap: 10px 26px; list-style: none; margin: 2.25rem 0 0; padding: 0; }
.hero-points li { position: relative; padding-left: 24px; font-size: .93rem; color: #b7d0e4; }
.hero-points li::before {
  content: "";
  position: absolute; left: 0; top: .52em;
  width: 11px; height: 6px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* ---------- strip ---------- */
.strip { background: var(--bg-alt); border-bottom: 1px solid var(--line); }
.strip-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding: 32px 24px;
}
.strip-grid div { display: flex; flex-direction: column; position: relative; }
.strip-grid div + div::before {
  content: "";
  position: absolute;
  left: -12px; top: 4px; bottom: 4px;
  width: 1px;
  background: var(--line);
}
.strip-icon { color: var(--accent); width: 17px; height: 17px; margin-bottom: 12px; }
.strip-grid strong { color: var(--brand); font-size: 1.35rem; letter-spacing: -.02em; }
.strip-grid span { font-size: .88rem; color: var(--muted); }

/* ---------- sections ---------- */
.section { padding: clamp(56px, 7vw, 92px) 0; }
.section-alt { background: var(--bg-alt); border-block: 1px solid var(--line); }
.section.narrow { padding: clamp(56px, 8vw, 100px) 0; }
.section-head { max-width: 660px; margin-bottom: 2.75rem; }
.section-head h2::after {
  content: "";
  display: block;
  width: 46px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent);
  margin-top: 18px;
}
.section-head-center h2::after { margin-inline: auto; }
.section-sub { font-size: 1.02rem; }
.page-head { background: var(--bg-alt); border-bottom: 1px solid var(--line); padding: clamp(48px, 6vw, 76px) 0; }
.page-head .lede { max-width: 62ch; }
.note { margin-top: 2rem; font-size: .93rem; color: var(--muted); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 18px;
}
.card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 24px 24px;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.card { position: relative; overflow: hidden; }
.card::before {
  content: "";
  position: absolute; inset: 0 auto auto 0;
  height: 3px; width: 100%;
  background: linear-gradient(90deg, var(--accent), #f0a565);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .22s ease;
}
.card:hover::before { transform: scaleX(1); }
.card:hover { border-color: #b9d2e4; box-shadow: var(--shadow); transform: translateY(-2px); }
.card h3 { margin-bottom: .35em; }
.card p { margin: 0; font-size: .93rem; }

.reason-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 20px; }
.reason { border-top: 3px solid var(--accent); padding-top: 18px; }
.reason h3 { margin-bottom: .4em; }
.reason p { margin: 0; font-size: .95rem; }

.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 32px; }
.steps-4 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }
.step { background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius); padding: 28px; }
.step-n { display: block; font-size: .82rem; font-weight: 700; letter-spacing: .14em; color: var(--accent); margin-bottom: 12px; }
.step p { margin: 0; font-size: .95rem; }

.cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(700px 320px at 92% -30%, rgba(224, 122, 47, .3), transparent 62%),
    linear-gradient(140deg, var(--brand-dark), var(--brand));
  color: #cfe1ee;
  padding: clamp(48px, 6vw, 76px) 0;
}
.cta::before {
  content: "";
  position: absolute; inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(110% 100% at 100% 0%, #000 15%, transparent 70%);
}
.cta-inner { display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.cta h2 { color: #fff; }
.cta p { max-width: 52ch; margin: 0; }
.cta-actions { display: flex; gap: 14px; flex-wrap: wrap; }

/* ---------- forms ---------- */
.form-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 48px; align-items: start; }
.quote-form fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 26px; margin: 0 0 24px; }
.quote-form legend { padding: 0 10px; font-weight: 700; color: var(--ink); font-size: .95rem; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px 18px; margin-bottom: 20px; }
.grid-2:last-child { margin-bottom: 0; }
.grid-2 > .field { margin-bottom: 0; }
.field { display: flex; flex-direction: column; margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }
.field label { font-size: .88rem; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.field small { margin-top: 5px; font-size: .8rem; color: var(--muted); }
.req { color: var(--accent); }

input[type="text"], input[type="email"], input[type="tel"], input[type="password"],
input[type="number"], select, textarea {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: .95rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid #c7d6e2;
  border-radius: 8px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
textarea { resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(14, 77, 125, .14);
}
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.form-actions { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.form-actions .muted { font-size: .85rem; max-width: 52ch; margin: 0; }

.form-aside { background: var(--bg-alt); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px; }
.form-aside h2 { font-size: 1.05rem; }
.tick-list { list-style: none; margin: 0 0 0; padding: 0; }
.tick-list li { position: relative; padding-left: 22px; margin-bottom: 10px; font-size: .9rem; }
.tick-list li::before {
  content: "";
  position: absolute; left: 0; top: .5em;
  width: 10px; height: 5px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

.alert { border-radius: 8px; padding: 14px 16px; margin-bottom: 22px; font-size: .92rem; }
.alert-error { background: #fdf0ec; border: 1px solid #f0c3b4; color: #8d3417; }
.alert-error ul { margin: .5rem 0 0; padding-left: 1.1rem; }
.alert-ok { background: #eaf6ee; border: 1px solid #b6ddc3; color: #1e6236; }
/* Neither good news nor bad — a standing fact about the page you are on, such
   as an order being archived. Quiet on purpose: green would read as something
   having just gone right, and nothing just happened. */
.alert-note { background: var(--bg-alt); border: 1px solid var(--line); color: var(--body); }

.confirm { max-width: 640px; }
.confirm-mark {
  width: 54px; height: 54px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--brand-tint);
  color: var(--brand);
  font-size: 1.6rem;
  margin-bottom: 22px;
}

/* ---------- footer ---------- */
.site-footer {
  background: var(--brand-darker);
  color: #a9c3d6;
  padding: 60px 0 0;
  margin-top: 0;
  border-top: 3px solid var(--accent);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.7fr repeat(3, minmax(0, 1fr)) 1.2fr;
  gap: 40px 32px;
  padding-bottom: 44px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .55rem; font-size: .9rem; }
.footer-brand-col p { max-width: 34ch; }
.footer-badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.chip {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .06);
  font-size: .76rem;
  color: #cfe1ee;
}
.footer-address { font-style: normal; font-size: .88rem; line-height: 1.6; color: #7f9cb3; margin-top: .4rem; }
.footer-brand { gap: 10px; margin-bottom: 14px; color: #fff; }
.footer-brand.brand-image { width: 300px; max-width: 100%; padding: 4px 12px; border-radius: 10px; background: #fff; }
.footer-brand .logo-mark { color: #2b82bd; }
.footer-brand strong { color: #fff; font-size: 1rem; }
.site-footer h3 { color: #fff; font-size: .82rem; text-transform: uppercase; letter-spacing: .1em; margin-bottom: 1rem; }
.site-footer p { font-size: .9rem; margin: 0 0 .55rem; }
.site-footer .muted { color: #7f9cb3; }
.site-footer a { color: #cfe1ee; }
.site-footer a:hover { color: #fff; }
.footer-legal {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding: 20px 24px;
  font-size: .82rem;
  color: #7f9cb3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 26px;
}
.footer-legal-links { display: flex; flex-wrap: wrap; gap: 16px; }
.footer-legal-links a { color: #9fbdd4; }

/* ---------- admin ---------- */
body.admin { background: var(--bg-alt); }
.admin-header { background: #fff; }
.admin-wrap { padding-block: 36px 64px; }
.admin-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 28px; }
.admin-head h1 { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: .25em; }
.admin-head p { margin: 0; font-size: .9rem; }
.crumb { font-size: .9rem; margin-bottom: 18px; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 14px; margin-bottom: 26px; }
.stat { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; display: flex; flex-direction: column; }
.stat strong { font-size: 1.7rem; color: var(--ink); line-height: 1.15; letter-spacing: -.03em; }
.stat span { font-size: .82rem; color: var(--muted); }
.stat-new strong { color: var(--accent); }
.stat-won strong { color: #1e6236; }

.tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--body);
  text-decoration: none;
  font-size: .875rem;
  font-weight: 500;
}
.tab span { color: var(--muted); font-size: .8rem; }
.tab:hover { border-color: #b9d2e4; color: var(--ink); }
.tab-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.tab-on span { color: rgba(255, 255, 255, .75); }

.table-wrap { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow-x: auto; }
.data-table { width: 100%; border-collapse: collapse; min-width: 780px; }
.data-table th, .data-table td { padding: 14px 16px; text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
.data-table th { font-size: .76rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); background: var(--bg-alt); }
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:hover { background: #fafcfe; }
.data-table strong { color: var(--ink); }
.empty { text-align: center; color: var(--muted); padding: 44px 16px; }

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .76rem;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge-pending { background: #fdf1e7; color: #96491a; border-color: #f2cfae; }
.badge-approved { background: #eaf3f9; color: var(--brand); border-color: #bcd8ea; }
.badge-active { background: #eaf6ee; color: #1e6236; border-color: #b6ddc3; }
.badge-declined { background: #fdf0ec; color: #8d3417; border-color: #f0c3b4; }
.badge-canceled { background: #f4f5f6; color: #64707b; border-color: #dfe3e7; }

.detail-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 20px; margin-bottom: 20px; }
.panel { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 26px; margin-bottom: 20px; }
.panel h2 { font-size: 1.05rem; margin-bottom: 1rem; }
.panel h3 { font-size: .92rem; margin: 1.4rem 0 .4rem; }
.spec-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; margin: 0 0 .5rem; }
.spec dt { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-bottom: 3px; }
.spec dd { margin: 0; color: var(--ink); font-size: .95rem; }

/* ---------- catalogue ---------- */
.card-link { display: block; text-decoration: none; color: inherit; }
.card-link .card-cta {
  display: inline-block;
  margin-top: 14px;
  font-size: .875rem;
  font-weight: 600;
  color: var(--brand);
  transition: transform .18s ease, color .18s ease;
}
.card-link:hover .card-cta { color: var(--accent); transform: translateX(3px); }
.card-link:hover h3 { color: var(--brand); }

.catalog-block { margin-bottom: 52px; }
.catalog-block:last-child { margin-bottom: 0; }
.catalog-head { margin-bottom: 20px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.catalog-head h2 { font-size: 1.35rem; margin-bottom: .25em; }
.catalog-head h2 a { color: var(--ink); text-decoration: none; }
.catalog-head h2 a:hover { color: var(--brand); }
.catalog-head p { margin: 0; font-size: .93rem; }

.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 18px; }
.product-card {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  text-decoration: none;
  color: inherit;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.product-card:hover { border-color: #b9d2e4; box-shadow: var(--shadow); transform: translateY(-2px); }
.product-card:hover h3 { color: var(--brand); }
.product-card h3 { margin-bottom: .3em; font-size: 1rem; }
.product-card p { margin: 0 0 16px; font-size: .88rem; color: var(--muted); flex: 1; }

/* ---------- coming soon ----------
   A card that cannot be ordered from is rendered as a plain element rather than
   a link, so it is already out of the tab order. These rules only have to make
   that visible: the artwork is dimmed, the hover lift is removed and a badge is
   laid over the picture. */
.card.is-soon,
.product-card.is-soon { position: relative; cursor: default; }
.card.is-soon:hover,
.product-card.is-soon:hover {
  border-color: var(--line);
  box-shadow: none;
  transform: none;
}
.card.is-soon:hover h3,
.product-card.is-soon:hover h3 { color: inherit; }

/* The picture, not the whole card, so the name and blurb stay readable. */
.is-soon .category-art,
.is-soon .product-photo,
.is-soon picture,
.is-soon img { opacity: .42; filter: saturate(.55); }

.is-soon h3,
.is-soon p { color: var(--muted); }

.soon-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-4deg);
  z-index: 2;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(17, 24, 31, .28);
  pointer-events: none;
}

/* Inline next to a category heading, where there is no picture to sit over. */
.soon-tag {
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: #f4f5f6;
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.panel-order.is-soon { background: #fbfbfc; border-style: dashed; }

.price { display: flex; align-items: baseline; gap: 8px; }
.price strong { font-size: 1.25rem; color: var(--ink); letter-spacing: -.02em; }
.price span { font-size: .82rem; color: var(--muted); }
.price-locked { color: var(--muted); font-size: .9rem; align-items: center; }
.price-locked .lock { font-size: .95rem; filter: grayscale(1); opacity: .65; }
.price-locked a { font-weight: 600; }
.price-lg { margin-bottom: 14px; }
.price-lg strong { font-size: 1.9rem; }
/* Square-inch products quote a method, not a figure, so the label carries less
   visual weight than a real price would. */
.price-calc strong { font-size: 1.02rem; font-weight: 600; }
.price-lg.price-calc strong { font-size: 1.35rem; }

/* ---------- account status ---------- */
.status-panel { border-left: 4px solid var(--line); }
.status-panel h2 { margin-bottom: .4em; }
.status-panel p { margin-bottom: .75rem; }
.status-good { border-left-color: #2e8b57; }
.status-wait { border-left-color: var(--accent); }
.status-bad { border-left-color: #b4472c; }

.button-row { display: flex; flex-wrap: wrap; gap: 12px; }

.panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px; margin-bottom: 20px;
}
.panel-head h2 { margin-bottom: .25em; }
.panel-head p { margin: 0; font-size: .9rem; }
.from-env { color: var(--accent) !important; }

.input-prefix { position: relative; display: flex; align-items: center; }
.input-prefix > span {
  position: absolute; left: 13px;
  color: var(--muted); font-size: .95rem; pointer-events: none;
}
.input-prefix input { padding-left: 28px; }

/* Square injects its own iframe here; give it room and a matching frame. */
#card-container { min-height: 90px; }

.login-wrap { min-height: calc(100vh - 72px); display: grid; place-items: center; padding: 40px 24px; }
.login-card { background: #fff; border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); padding: 36px; width: 100%; max-width: 400px; }
.login-card h1 { font-size: 1.5rem; margin-bottom: .2em; }
.login-card > .muted { margin-bottom: 1.75rem; font-size: .9rem; }
.login-card .btn { margin-top: 6px; }
.login-card .small { margin: 1.25rem 0 0; text-align: center; }

/* ---------- customer search ---------- */
.search-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; }
.search-bar input[type="search"] {
  flex: 1 1 280px; min-width: 0;
  padding: 10px 14px; font: inherit; font-size: .95rem;
  color: var(--ink); background: #fff;
  border: 1px solid var(--line); border-radius: 8px;
}
.search-bar input[type="search"]:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.search-bar .btn { flex: 0 0 auto; }

.narrow-wrap { max-width: 640px; }
.head-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.warn-text { color: #a2521c; }

/* ---------- destructive actions ---------- */
.panel-danger { border-color: #e8bfb2; }
.panel-danger h1, .panel-danger h2 { color: #8d3417; }
.btn-danger { background: #b4472c; color: #fff; border-color: #b4472c; }
.btn-danger:hover { background: #98371f; border-color: #98371f; color: #fff; }

/* ---------- viewing as a customer ---------- */
.impersonation-bar {
  position: sticky; top: 0; z-index: 20;
  background: var(--brand-darker); color: #fff; font-size: .9rem;
}
.impersonation-inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; padding-block: 10px;
}
.impersonation-bar strong { color: #fff; }

/* A preview touches nobody's account; it must not look like the bar that does. */
.impersonation-bar.preview-bar { background: #2f5d50; }


/* ---------- accessibility ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--brand);
  color: #fff;
  padding: 10px 18px;
  border-radius: 0 0 var(--radius) 0;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 0; color: #fff; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

html { scroll-behavior: smooth; scroll-padding-top: 88px; }

/* ---------- scroll reveal (only ever active when JS has run) ---------- */
.js .reveal { opacity: 0; transform: translateY(16px); }
.js .reveal.in {
  opacity: 1;
  transform: none;
  transition: opacity .55s cubic-bezier(.22, .61, .36, 1), transform .55s cubic-bezier(.22, .61, .36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
}

/* ---------- icons ---------- */
.icon { width: 18px; height: 18px; flex: none; }
.icon-inline { width: 12px; height: 12px; vertical-align: -1px; margin-right: 7px; color: var(--accent); }

/* ---------- hero illustration ---------- */
.hero-visual { display: flex; flex-direction: column; align-items: stretch; gap: 24px; }
.hero-art {
  display: block;
  width: 100%;
  max-width: 480px;
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 30px 50px rgba(2, 16, 28, .45));
}
.hero-figures {
  display: flex;
  gap: 10px;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
}
.hero-figure {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .14);
  backdrop-filter: blur(4px);
}
.hero-figure strong { color: #fff; font-size: 1.15rem; letter-spacing: -.02em; line-height: 1.2; }
.hero-figure span { font-size: .76rem; color: #9dc4e0; }

/* ---------- buttons, extra sizes ---------- */
.btn-lg { padding: 15px 28px; font-size: 1rem; }
.btn-accent { box-shadow: 0 6px 18px rgba(224, 122, 47, .28); }
.btn-accent:hover { box-shadow: 0 8px 22px rgba(224, 122, 47, .34); }

/* ---------- section heads ---------- */
.section-head-center { margin-inline: auto; text-align: center; }
.section-head-center .eyebrow { text-align: center; }
.section-head h2 { text-wrap: balance; }

/* ---------- cards with icons ---------- */
.card-icon, .reason-icon {
  display: inline-grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 10px;
  background: var(--brand-tint);
  color: var(--brand);
  margin-bottom: 16px;
}
.card-link:hover .card-icon { background: var(--accent-tint); color: var(--accent); }
.reason {
  border-top: 0;
  padding: 26px 26px 24px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.reason:hover { border-color: #b9d2e4; box-shadow: var(--shadow); transform: translateY(-2px); }
.reason-icon { background: var(--accent-tint); color: var(--accent); }

/* ---------- steps as a connected run ---------- */
.step { position: relative; box-shadow: var(--shadow-sm); }
.step h3 { margin-bottom: .35em; }
.steps-4 .step::after {
  content: "";
  position: absolute;
  top: 46px; right: -14px;
  width: 8px; height: 8px;
  border-top: 2px solid var(--line);
  border-right: 2px solid var(--line);
  transform: rotate(45deg);
}
.steps-4 .step:last-child::after { display: none; }

/* ---------- pricing panel ---------- */
.price-panel {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  background: #fff;
}
.price-panel-main { padding: clamp(28px, 4vw, 44px); }
.price-panel-label {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .13em;
  font-weight: 700; color: var(--accent); margin-bottom: 1.4rem;
}
.price-panel-figure { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; margin-bottom: 1.5rem; }
.price-panel-figure strong { font-size: clamp(2.4rem, 5vw, 3.2rem); color: var(--ink); letter-spacing: -.035em; line-height: 1; }
.price-panel-figure span { font-size: .95rem; color: var(--muted); }
.price-panel-list { columns: 2; column-gap: 40px; margin-bottom: 2rem; }
.price-panel-list li { font-size: .97rem; margin-bottom: .85rem; }
.price-panel-list li { break-inside: avoid; }
.price-panel-side {
  background: var(--bg-alt);
  border-left: 1px solid var(--line);
  padding: clamp(28px, 4vw, 40px);
}
.price-panel-side h3 { font-size: .95rem; margin: 0 0 .5rem; }
.price-panel-side h3 + p { margin-bottom: 1.5rem; }
.price-panel-side p { font-size: .9rem; }

/* ---------- FAQ ---------- */
.faq-layout {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
}
.faq-layout .section-head { margin-bottom: 0; position: sticky; top: 100px; }
.faq-list { display: flex; flex-direction: column; gap: 12px; }
.faq {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  padding: 4px 22px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.faq[open] { border-color: #b9d2e4; box-shadow: var(--shadow-sm); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 30px 16px 0;
  font-weight: 600;
  color: var(--ink);
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute; right: 4px; top: 22px;
  width: 9px; height: 9px;
  border-right: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: rotate(45deg);
  transition: transform .18s ease;
}
.faq[open] summary::after { transform: rotate(-135deg); }
.faq p { margin: 0 0 18px; font-size: .95rem; max-width: 68ch; }

/* ---------- policy documents ---------- */
.page-head-slim { padding: clamp(40px, 5vw, 60px) 0; }
.legal-layout {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
}
.legal-toc { position: sticky; top: 100px; }
.legal-toc h2 { font-size: .78rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); }
.legal-toc ol { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
.legal-toc li { margin-bottom: .5rem; }
.legal-toc a { font-size: .89rem; text-decoration: none; color: var(--body); }
.legal-toc a:hover { color: var(--brand); text-decoration: underline; }
.legal-doc { max-width: 74ch; }
.legal-doc section { margin-bottom: 2.75rem; scroll-margin-top: 96px; }
.legal-doc section:last-child { margin-bottom: 0; }
.legal-doc h2 { font-size: 1.3rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line); }
.legal-doc ul, .legal-doc ol { padding-left: 1.2rem; margin: 0 0 1rem; }
.legal-doc li { margin-bottom: .5rem; }
.legal-doc strong { color: var(--ink); }
.legal-address { font-style: normal; color: var(--ink); line-height: 1.7; }
.legal-callout {
  list-style: none;
  margin: 0;
  padding: 24px 26px;
  background: var(--brand-tint);
  border: 1px solid #cfe2ef;
  border-radius: var(--radius);
}
.legal-callout li { position: relative; padding-left: 26px; margin-bottom: .85rem; }
.legal-callout li:last-child { margin-bottom: 0; }
.legal-callout li::before {
  content: "";
  position: absolute; left: 0; top: .55em;
  width: 11px; height: 6px;
  border-left: 2px solid var(--brand);
  border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);
}

/* ---------- contact ---------- */
.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.contact-card { margin-bottom: 0; }
.contact-card h2 { font-size: .78rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin-bottom: .6rem; }
.contact-line { font-size: 1.12rem; color: var(--ink); font-weight: 600; margin-bottom: .5rem; }
.contact-address { font-style: normal; font-weight: 500; font-size: 1rem; line-height: 1.6; }
.contact-card .muted { font-size: .88rem; margin: 0; }
.contact-footnote { margin-top: 24px; }
.contact-footnote .tick-list li { margin-bottom: .7rem; font-size: .95rem; }

/* ---------- consent and disclosure ---------- */
.consent {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-alt);
  font-size: .9rem;
  line-height: 1.55;
  margin-bottom: 18px;
}
.consent input[type="checkbox"] { margin-top: .25em; width: 17px; height: 17px; accent-color: var(--brand); flex: none; }
.terms-box {
  border: 1px solid #cfe2ef;
  background: var(--brand-tint);
  border-radius: var(--radius);
  padding: 20px 22px;
  margin-bottom: 20px;
}
.terms-box h3 { font-size: .95rem; margin: 0 0 .75rem; }
.terms-box ul { margin: 0 0 .75rem; padding-left: 1.1rem; }
.terms-box li { font-size: .9rem; margin-bottom: .45rem; }
.terms-box p { margin: 0; }

@media (max-width: 1000px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-visual { align-items: flex-start; }
  .hero-art { max-width: 400px; margin: 0; }
  .hero-figures { max-width: 460px; margin: 0; }
  .price-panel { grid-template-columns: 1fr; }
  .price-panel-side { border-left: 0; border-top: 1px solid var(--line); }
  .faq-layout { grid-template-columns: 1fr; }
  .faq-layout .section-head { position: static; margin-bottom: 1.5rem; }
  .legal-layout { grid-template-columns: 1fr; }
  .legal-toc { position: static; border-bottom: 1px solid var(--line); padding-bottom: 20px; }
  .legal-toc ol { columns: 2; column-gap: 28px; }
  .legal-toc hr, .legal-toc p { display: none; }
}

@media (max-width: 900px) {
  .form-wrap { grid-template-columns: 1fr; gap: 32px; }
  .detail-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .strip-grid { grid-template-columns: repeat(2, 1fr); }
  .steps-4 .step::after { display: none; }
}

@media (max-width: 660px) {
  .header-inner { flex-wrap: wrap; gap: 12px; padding-block: 12px; }
  .site-nav { gap: 16px; width: 100%; flex-wrap: wrap; font-size: .9rem; }
  .brand-text em { display: none; }
  .footer-grid { grid-template-columns: 1fr; gap: 28px; }
  .cta-inner { flex-direction: column; align-items: flex-start; }
  .admin-head { flex-direction: column; }
  .price-panel-list { columns: 1; }
  .legal-toc ol { columns: 1; }
  .hero-figures { flex-direction: column; }
  .hero-figure { flex-direction: row; align-items: baseline; gap: 10px; }
  .footer-legal { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* ------------------------------------------------------------ job pricing */

/* Forms on this page return to the block they belong to via a fragment, and the
   site header is sticky, so anchored sections need to clear it. */
.admin-wrap .panel[id] { scroll-margin-top: 90px; }

/* Kept for narrow screens; column sizing lives in the sheet table block below. */
.table-scroll { overflow-x: auto; margin: 0 -4px; padding: 0 4px; }
/* A row that is still on the list but not in use — a box size kept for its
   history rather than picked for new jobs. */
.row-muted { opacity: .55; }

.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px 18px;
}
.overhead-group {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 20px 20px;
  margin: 0 0 18px;
}
.overhead-group legend {
  padding: 0 8px;
  font-size: .74rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  font-weight: 600;
}
.overhead-group .field { margin: 0; }
.overhead-group label { font-size: .86rem; }

.pricing-add {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.pricing-add input[type="text"] { flex: 1 1 200px; min-width: 0; }
.pricing-add input[type="number"] { width: 120px; }
.pricing-add .input-prefix { width: 140px; }

.data-table td .input-prefix { margin: 0; }
.data-table td input, .data-table td select { width: 100%; min-width: 90px; }
.data-table .num { text-align: right; }

/* The service prices behind the label picker. Three narrow columns, so the
   780px floor the wide admin tables need would only force a scrollbar onto a
   table that fits comfortably. The row for the service the customer actually
   bought is tinted, because it is the one every other row is being read
   against. */
.rate-table { min-width: 0; }
.rate-table caption { caption-side: top; text-align: left; padding: 0 0 8px; }
.data-table tbody tr.is-current { background: var(--bg-alt); }
.data-table tbody tr.is-current:hover { background: var(--bg-alt); }
.data-table .num input { text-align: right; }
.data-table td.computed {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}

/* The buttons that end a table row. The flex box belongs on a div inside the
   cell, never on the `<td>` itself: a cell that is a flex container stops being
   a table-cell, so `vertical-align` no longer reaches it and the browser aligns
   the anonymous cell it gets wrapped in on the baseline — which rode the button
   up to the first line of the two-line customer cell on the orders list while
   every other cell in the row stayed centred. `align-items: center` then keeps
   each button at its natural height instead of stretching it to the row. */
.row-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.btn-small { padding: 6px 12px; font-size: .82rem; }

.rate-form { margin-top: 18px; }
.rate-form .field { max-width: 320px; }

/* The shop-rate arithmetic, shown as the division it actually is. */
.rate-callout {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  margin-top: 20px;
  padding: 18px 22px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.rate-callout strong {
  display: block;
  font-size: 1.35rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.rate-label {
  display: block;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  margin-bottom: 2px;
}
.rate-op { font-size: 1.3rem; color: var(--muted); }
.rate-result strong { color: var(--brand); }
.rate-unit { font-size: .9rem; font-weight: 400; color: var(--muted); }

.quote-out {
  margin-top: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.quote-layout { padding: 18px 22px; background: var(--brand-tint); }
.quote-layout p { margin: 0 0 .5rem; }
.quote-layout p:last-child { margin-bottom: 0; font-size: .9rem; }
.quote-table { min-width: 0; }
.quote-table .num { font-variant-numeric: tabular-nums; }
.quote-rate td { color: var(--brand); font-weight: 600; }
.quote-total td {
  border-top: 2px solid var(--line);
  font-weight: 600;
  color: var(--ink);
  font-size: 1.05rem;
}

@media (max-width: 720px) {
  .rate-callout { gap: 12px; }
  .rate-op { display: none; }
  .pricing-add input[type="number"], .pricing-add .input-prefix { width: 100%; }
}

/* ------------------------------------------------- full-width admin pages */

/* The public site stays at a readable 1140px, but admin is data entry: the
   tables were the thing being squeezed, so these pages run edge to edge. */
.admin-wrap { max-width: none; padding-inline: clamp(24px, 3vw, 48px); }
body.admin .header-inner { max-width: none; padding-inline: clamp(24px, 3vw, 48px); }

/* Confirm dialogs are prose, not a grid — keep them narrow enough to read. */
.admin-wrap.narrow-wrap { max-width: 640px; }

/* Removing the cap must not stretch a lone text box across a 2560px monitor.
   Table inputs are untouched: they still fill their column. */
.admin-wrap .field > input,
.admin-wrap .field > select,
.admin-wrap .field > textarea,
.admin-wrap .field > .input-prefix { max-width: 460px; }

/* With the extra room the sheet table usually fits; the wrapper stays for
   narrow screens. Tracks .sheet-table's min-width plus the page and panel
   padding — below this the table really is scrolling and keeps its inset. */
@media (min-width: 1900px) {
  .table-scroll { margin: 0; padding: 0; }
}

/* ------------------------------------------- sheet table column sizing */

/* Thirteen columns fit because each stopped being padded for a prose table and
   no number box reserves room for spinners it never needed. */
.sheet-table th, .sheet-table td { padding: 10px 8px; }
.sheet-table td input, .sheet-table td select { min-width: 0; width: 100%; }
.sheet-table td .input-prefix { width: auto; }

/* Spinner arrows cost roughly 18px in each of seven numeric columns. These are
   typed, not stepped, so the arrows buy nothing here. */
.sheet-table input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
.sheet-table input[type="number"]::-webkit-outer-spin-button,
.sheet-table input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.sheet-table .row-actions { gap: 4px; }
.sheet-table .btn-small { padding: 6px 9px; }

/* The paper name needs more room than the numeric fields beside it. */
.field-wide { grid-column: span 2; }
@media (max-width: 700px) { .field-wide { grid-column: auto; } }

/* ------------------------------ paper catalog row alignment */

/* Cells were top-aligned, which is right for a prose table and wrong for a row
   of controls — it left each box hanging at a different point. */
.sheet-table th, .sheet-table td { vertical-align: middle; }

/* Every control in the row now shares the base height (11px vertical padding).
   Horizontal padding is trimmed instead, so matching the select's height costs
   almost no width and the table still fits without scrolling. */
.sheet-table td input, .sheet-table td select { padding-left: 8px; padding-right: 8px; }
.sheet-table td .input-prefix > span { left: 8px; }
.sheet-table td .input-prefix input { padding-left: 19px; }

/* Every column now carries its longest real value without clipping: a 26-char
   stock name, a 12-digit part number, "Index / LB" in the type select, 12.000
   thousandths, $189.00 a carton, plus the drag handle in front of them all.
   Widths were measured against DejaVu Sans,
   which runs wider than the system faces the page actually uses, so there is
   slack in hand. Column 2 is the part number, so everything past the name sits
   one place further right.

   The actions column is the one that used to swallow the leftover width — it
   was the only column without a width, so auto layout handed it every spare
   pixel and left a gap between $/sheet and Save while the inputs beside it were
   squeezed. Shrink-wrapping it (width: 1%) sends that slack back to the columns
   that hold the typing. */
.sheet-table { min-width: 1740px; }
.sheet-table th:nth-child(1), .sheet-table td:nth-child(1) { width: 44px; }
.sheet-table th:nth-child(2), .sheet-table td:nth-child(2) { min-width: 252px; }
.sheet-table th:nth-child(3), .sheet-table td:nth-child(3) { width: 168px; }
.sheet-table th:nth-child(4), .sheet-table td:nth-child(4) { width: 176px; }
.sheet-table th:nth-child(5), .sheet-table td:nth-child(5) { width: 138px; }
.sheet-table th:nth-child(6), .sheet-table td:nth-child(6),
.sheet-table th:nth-child(7), .sheet-table td:nth-child(7) { width: 84px; }
.sheet-table th:nth-child(8), .sheet-table td:nth-child(8) { width: 106px; }
.sheet-table th:nth-child(9), .sheet-table td:nth-child(9) { width: 78px; }
.sheet-table th:nth-child(10), .sheet-table td:nth-child(10) { width: 96px; }
.sheet-table th:nth-child(11), .sheet-table td:nth-child(11) { width: 86px; }
.sheet-table th:nth-child(12), .sheet-table td:nth-child(12) { width: 108px; }
.sheet-table th:nth-child(13), .sheet-table td:nth-child(13) { width: 82px; }
.sheet-table th:nth-child(14), .sheet-table td:nth-child(14) { width: 88px; }
.sheet-table th:nth-child(15), .sheet-table td:nth-child(15) { width: 1%; white-space: nowrap; }

/* A heading names the column rather than lining up with any one value in it, so
   over a stack of boxes it belongs centred — including the numeric columns,
   which inherit a right-aligned heading from .data-table otherwise. */
.sheet-table th,
.sheet-table th.num { text-align: center; }

/* ---------------------------------------- derived grams per sheet */

/* A box the page fills in for you, not one you are being asked to fill. It
   stays a normal input — readonly, so the value still submits — but reads as an
   answer: muted, on the panel's own tint, with no editing affordance. */
.computed-input,
.sheet-table td input.computed-input {
  background: var(--bg-alt);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  cursor: default;
}
.computed-input:focus {
  outline: none;
  border-color: var(--line);
  box-shadow: none;
}

/* ------------------------------------------------ sheet imposition preview */

.impose-row {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
  padding: 18px 22px;
}
.impose-row .quote-table { flex: 1 1 320px; }
.impose-svg {
  flex: 0 0 auto;
  background: #fff;
  border-radius: 4px;
  box-shadow: var(--shadow-sm);
  max-width: 100%;
  height: auto;
}

/* =========================================== product pages and the editor */

.detail-main, .detail-side { min-width: 0; }

/* The photo is the product's own, not a stock illustration, so it is shown
   whole — letterboxed on its own ground rather than cropped to a shape. */
.product-photo {
  margin: 0 0 20px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.product-photo img { display: block; width: 100%; height: auto; }

.prose p { margin: 0 0 1rem; max-width: 68ch; }
.prose p:last-child { margin-bottom: 0; }

.spec-list dt {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin-bottom: 3px;
}
.spec-list dd { margin: 0 0 4px; color: var(--ink); font-size: .95rem; }

/* ---------------------------------------------------- catalogue console */

.catalog-table th:first-child, .catalog-table td:first-child { width: 92px; }
.admin-thumb {
  display: block; width: 76px; height: 54px; border-radius: 6px;
  object-fit: cover; background: var(--bg-alt); border: 1px solid var(--line);
}
.admin-thumb-empty {
  display: flex; align-items: center; justify-content: center;
  border-style: dashed; font-size: .68rem; color: var(--muted); text-align: center;
}

/* The current photo sits beside its fields rather than above them, so what you
   are replacing stays in view while you type the alt text for it. */
.photo-row { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start; }
.photo-current { flex: 0 0 260px; margin: 0; }
.photo-current img {
  display: block; width: 100%; height: auto; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--bg-alt); margin-bottom: 6px;
}
.photo-empty {
  display: flex; align-items: center; justify-content: center;
  min-height: 150px; border: 1px dashed var(--line);
  border-radius: var(--radius); background: var(--bg-alt);
}
.photo-fields { flex: 1 1 320px; min-width: 0; }
.photo-fields .field:last-child { margin-bottom: 0; }

/* A checkbox is a choice, not a text box: it must not stretch to the column. */
.field .check { display: flex; align-items: flex-start; gap: 10px; font-weight: 500; }
.field .check input[type="checkbox"] { width: auto; margin-top: .18em; flex: 0 0 auto; }

/* Length guides on the search fields. Over the mark is a warning, never a
   block — Google truncates on pixel width, so the number is advice. */
.char-count {
  display: block; margin-top: 4px; font-size: .78rem;
  color: var(--muted); font-variant-numeric: tabular-nums; text-align: right;
}
.char-count.over { color: var(--accent-dark); font-weight: 600; }

.slug-url { display: block; margin-bottom: 4px; color: var(--brand); word-break: break-all; }

.form-actions-inline {
  flex-direction: row; flex-wrap: wrap; align-items: center; gap: 12px;
  margin-bottom: 40px;
}
.form-actions-inline .btn-danger { margin-left: auto; }

/* ================================================= products console */

/* One bar under the page title: products, categories and the pictures they
   share are three views of the same thing, not three destinations. */
.subnav {
  display: flex; flex-wrap: wrap; gap: 4px;
  border-bottom: 1px solid var(--line); margin-bottom: 22px;
}
.subtab {
  padding: 10px 16px; text-decoration: none; color: var(--muted);
  font-size: .92rem; font-weight: 600; border-bottom: 2px solid transparent;
  margin-bottom: -1px; border-radius: 6px 6px 0 0;
}
.subtab:hover { color: var(--ink); background: var(--bg-alt); }
.subtab.is-here { color: var(--brand); border-bottom-color: var(--brand); }

/* ---------------------------------------------------- the image picker */

/* Radios, so choosing a picture is one field in the form that surrounds it and
   needs no script. The control itself is hidden but still focusable, and the
   card it labels shows the focus ring in its place. */
.image-picker {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 12px; margin-bottom: 22px; max-height: 420px; overflow-y: auto;
  padding: 4px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-alt);
}
.pick { display: block; cursor: pointer; }
.pick input {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.pick-body {
  display: block; background: #fff; border: 2px solid var(--line);
  border-radius: 10px; padding: 6px; height: 100%;
}
.pick input:checked ~ .pick-body { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(14, 77, 125, .14); }
.pick input:focus-visible ~ .pick-body { outline: 2px solid var(--brand); outline-offset: 2px; }
.pick-art {
  display: block; width: 100%; height: 84px; object-fit: contain;
  background: var(--bg-alt); border-radius: 6px;
}
.pick-none {
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: .8rem; border: 1px dashed var(--line);
}
.pick-name {
  display: block; margin-top: 6px; font-size: .72rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------------------------------------------------- the library grid */

.lib-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px;
}
.lib-card {
  margin: 0; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: #fff; display: flex; flex-direction: column;
}
.lib-shot { display: block; background: var(--bg-alt); }
.lib-shot img { display: block; width: 100%; height: 170px; object-fit: contain; }
.lib-card figcaption { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 8px; }
.lib-card figcaption p { margin: 0; }
.lib-name { font-weight: 600; font-size: .86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-alt { display: flex; gap: 6px; }
.lib-alt input { min-width: 0; padding: 8px 10px; font-size: .85rem; }
.lib-alt .btn { flex: 0 0 auto; }
.lib-usage a { color: var(--brand); }
.lib-card .btn-danger { align-self: flex-start; }

/* Category rows are edited in place like the paper catalogue. */
.category-table { min-width: 1180px; }
.category-table th, .category-table td { padding: 10px 8px; vertical-align: middle; }
.category-table td input, .category-table td select { min-width: 0; width: 100%; padding-left: 8px; padding-right: 8px; }
.category-table th:first-child, .category-table td:first-child { width: 92px; }
.category-table th:nth-child(4), .category-table td:nth-child(4) { min-width: 260px; }
.category-table th:nth-child(6), .category-table td:nth-child(6) { width: 88px; }
.category-table th:nth-child(7), .category-table td:nth-child(7) { width: 92px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The settings page runs two subjects — the business, then the engine that
   prices its work. A rule and a heading separate them without a second page. */
.settings-rule {
  border: 0; border-top: 1px solid var(--line);
  margin: 40px 0 8px;
}
.admin-wrap .section-title { font-size: 1.35rem; margin-bottom: .25rem; }

/* ------------------------------------------- reorderable catalogue rows */

/* The handle is the only part of the row that starts a drag, so the inputs
   beside it still select text normally. touch-action keeps a drag on a phone
   from scrolling the page instead of moving the row. */
.drag-cell { text-align: center; }
.drag-handle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 30px; padding: 0;
  background: none; border: 1px solid transparent; border-radius: 6px;
  color: var(--muted); font-size: 1rem; line-height: 1;
  cursor: grab; touch-action: none;
}
.drag-handle:hover { background: var(--bg-alt); border-color: var(--line); color: var(--ink); }
.drag-handle:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.drag-handle:active { cursor: grabbing; }

/* While a row is moving, the rest of the table steps back so the one in hand
   reads as the thing being placed. */
.sheet-table tbody.is-reordering tr { transition: background-color .12s ease; }
.sheet-table tbody.is-reordering tr:not(.is-dragging) { background: var(--bg-alt); }
.sheet-table tr.is-dragging {
  background: var(--brand-tint);
  box-shadow: 0 2px 10px rgba(16, 32, 46, .18);
}
.sheet-table tr.is-dragging .drag-handle { cursor: grabbing; color: var(--brand); }

.order-status { margin: 0 0 10px; font-size: .85rem; color: var(--muted); min-height: 1.2em; }
.order-status.is-ok { color: var(--brand); }
.order-status.is-error { color: var(--accent-dark); font-weight: 600; }
.order-save { margin-bottom: 12px; }

/* ---------------------------------- materials that follow the calc type */

/* Each group is a fieldset so the browser groups the fields for a screen
   reader too, not only visually. Hidden by the script when the chosen
   calculation type does not use them; with no script they are all visible,
   which is what the form did before. */
.calc-group {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px 6px; margin: 0 0 20px; background: var(--bg-alt);
}
.calc-group > legend {
  padding: 0 8px; font-size: .78rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
}

/* A shortlist ticked out of a long catalogue: it scrolls rather than pushing
   the rest of the form off the screen. */
.choice-box {
  max-height: 260px; overflow-y: auto;
  border: 1px solid #c7d6e2; border-radius: 8px; background: #fff;
  padding: 6px;
}
.choice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 7px 8px; border-radius: 6px; cursor: pointer;
}
.choice:hover { background: var(--bg-alt); }
.choice input[type="checkbox"] { width: auto; flex: 0 0 auto; margin-top: .2em; }
.choice-text { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.choice-text strong { font-weight: 600; font-size: .9rem; }

/* The stocks a product offers, on the public page. */
.stock-list { list-style: none; margin: 0; padding: 0; }
.stock-list li {
  padding: 8px 0; border-bottom: 1px solid var(--line);
  font-size: .95rem; color: var(--ink);
}
.stock-list li:last-child { border-bottom: 0; }

/* The packed order, under the cost breakdown it belongs to. */
.packed-out { margin-top: 18px; }
.packed-out h3 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin: 0 0 .5rem;
}
.packed-out .quote-table td { padding-top: 8px; padding-bottom: 8px; }
.packed-out p { margin: 8px 0 0; }

/* ------------------------------------------- papers, sizes and the choice */

.class-table { min-width: 880px; }
.class-table th, .class-table td { padding: 10px 8px; vertical-align: middle; }
.class-table td input { width: 100%; min-width: 0; padding-left: 8px; padding-right: 8px; }
.class-table th:nth-child(1), .class-table td:nth-child(1) { width: 240px; }
.class-table th:nth-child(3), .class-table td:nth-child(3) { min-width: 220px; }
.class-table th:nth-child(4), .class-table td:nth-child(4) { width: 88px; }

/* The size the engine picked, said plainly before the arithmetic behind it. */
.chosen-stock {
  background: var(--brand-tint); border-left: 3px solid var(--brand);
  padding: 10px 14px; border-radius: 0 8px 8px 0; margin-bottom: 12px;
}

.candidates { margin-top: 18px; }
.candidates h3 {
  font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin: 0 0 .5rem;
}
.candidates tr.is-chosen td { background: var(--brand-tint); font-weight: 600; }

.impose-download { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 16px; }
.impose-download .muted { flex: 1 1 260px; }

/* ============================================================ cart & orders */

.order-form .field-static {
  margin: 0; padding: 11px 0; font-size: .95rem; color: var(--ink); font-weight: 600;
}

.cart-line {
  display: flex; gap: 20px; align-items: flex-start;
  padding: 18px 0; border-bottom: 1px solid var(--line);
}
.cart-line:first-child { padding-top: 0; }
.cart-line:last-child { border-bottom: 0; padding-bottom: 0; }
.cart-line-main { flex: 1 1 auto; min-width: 0; }
.cart-line-main h3 { font-size: 1rem; margin: 0 0 4px; }
.cart-line-main p { margin: 0 0 4px; }
.cart-line-price { flex: 0 0 auto; text-align: right; display: flex; flex-direction: column; gap: 8px; }
.cart-line-price strong { font-size: 1.1rem; }
.cart-total .spec-list { margin-bottom: 1rem; }

.order-total { text-align: right; }
.order-total strong { display: block; font-size: 1.5rem; }

/* A line opens where it stands. <details> does the work, so the specification
   is one click from the summary and needs no script to get there. */
.line-item { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; }
.line-item[open] { border-color: var(--brand); }
.line-item > summary {
  display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
  padding: 14px 18px; cursor: pointer; list-style: none;
}
.line-item > summary::-webkit-details-marker { display: none; }
.line-item > summary::before {
  content: "\25B8"; color: var(--muted); transition: transform .12s ease; flex: 0 0 auto;
}
.line-item[open] > summary::before { transform: rotate(90deg); }
.line-item > summary:hover { background: var(--bg-alt); }
/* The line's own number — "00001-02" — set apart from the product name because
   it is the thing written on the job bag and read back over the phone. */
.line-ref {
  flex: 0 0 auto; font-weight: 700; font-size: .82rem; color: var(--brand);
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: 6px; padding: 3px 8px; white-space: nowrap;
}
.line-name { flex: 1 1 260px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.line-run { flex: 0 0 auto; font-size: .85rem; color: var(--body); font-variant-numeric: tabular-nums; }
.line-price { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; }

.line-body { padding: 4px 18px 18px; border-top: 1px solid var(--line); }
.line-body .spec-list { margin: 16px 0; }
.line-files { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }

/* A file that does not exist yet still has its place in the row, so the set of
   four reads the same on every line. */
.btn.is-disabled {
  opacity: .45; cursor: not-allowed; background: var(--bg-alt);
  color: var(--muted); border-color: var(--line);
}

/* The order form sits in the narrow column beside the photo, so its two-up
   field grid runs one field per row rather than squeezing a paper name into
   half of it. */
.panel-order .grid-2 { grid-template-columns: 1fr; }
.panel-order .field-wide { grid-column: auto; }

/* Each field reads across rather than down: the label on the left, what it is
   set to on the right. It halves the height of the block and lines every
   answer up in one column the eye can run down. */
.panel-order .field {
  display: grid;
  /* Wide enough that the longest label, "Print-ready PDF", stays on one line. */
  grid-template-columns: 8.25rem minmax(0, 1fr);
  align-items: center;
  column-gap: 12px;
  row-gap: 3px;
  margin-bottom: 8px;
}
.panel-order .field > label { margin: 0; align-self: center; }
.panel-order .field > small { grid-column: 2; margin-top: 0; }
/* The thickness note has no label: it is one sentence, so it runs the full
   width of the panel rather than stacking tall in the label column. */
.panel-order .order-thickness > p { grid-column: 1 / -1; margin: 0; }
.panel-order .field-static { margin: 0; font-size: .95rem; font-weight: 600; }
.panel-order input[type="file"] { font-size: .82rem; }

@media (max-width: 900px) {
  /* Full width again once the column is the whole page. */
  .panel-order .field { display: flex; }
  .panel-order .field > label { margin-bottom: 6px; }
}
.panel-order { border-color: var(--brand); }
.panel-order .btn-lg { width: 100%; }

/* ------------------------------- the photo and the order form, side by side */

/* One locked picture size for every product, so the catalogue does not change
   shape from page to page: a 700px square, which is a round number that fits
   the column at the 1140px page width with room to spare and divides evenly
   for the half and quarter sizes further down. The order block matches it, so
   the two always sit level. */
:root { --product-photo: 700px; }

/* Explicit placement rather than flow: the photo and the order block share the
   first row, so they are the same height, and the reading matter sits under
   them. */
.detail-grid.has-photo .product-photo { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.detail-grid .panel-order { grid-column: 2; grid-row: 1; margin-bottom: 0; }
.detail-grid .detail-main { grid-column: 1; grid-row: 2; }
.detail-grid .detail-side { grid-column: 2; grid-row: 2; }

/* A fixed square, whatever shape the photograph is. The picture is letterboxed
   inside it on its own ground rather than trimmed, because the product is the
   thing being shown and cropping it would cut the product. */
.detail-grid.has-photo .product-photo {
  display: flex;
  width: min(100%, var(--product-photo));
  height: min(100%, var(--product-photo));
  aspect-ratio: 1 / 1;
  justify-self: start;
}
.detail-grid.has-photo .product-photo img { width: 100%; height: 100%; object-fit: contain; }

/* The order block is the height of the picture beside it, so its contents have
   to fit that box — never scroll inside it. Nobody scrolls a panel they cannot
   see the bottom of, so anything that did not fit would simply be lost. The
   fields take the room above, the price, button and note are pinned below, and
   everything is sized so the whole form clears 700px with room to spare. */
.panel-order { display: flex; flex-direction: column; overflow: hidden; padding: 18px 20px; }
.detail-grid.has-photo .panel-order { height: var(--product-photo); }
.panel-order > h2 { margin-bottom: .5rem; }
.panel-order .order-form { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.panel-order .order-form > .grid-2 {
  flex: 1 1 auto;
  min-height: 0;
  align-content: start;
  margin-bottom: 4px;
}
.panel-order .order-price,
.panel-order .order-form > button,
.panel-order .order-note { flex: 0 0 auto; }

.panel-order .order-form { display: flex; flex-direction: column; }

@media (max-width: 900px) {
  .detail-grid .product-photo,
  .detail-grid .panel-order,
  .detail-grid .detail-main,
  .detail-grid .detail-side { grid-column: 1; grid-row: auto; }
  .panel-order, .detail-grid.has-photo .panel-order { overflow: visible; height: auto; }
  /* On a phone the column is the page, so the square follows the width. */
  .detail-grid.has-photo .product-photo { width: 100%; height: auto; }
}

/* ------------------------------------------------- the price on the button */

.order-price {
  display: flex; flex-direction: column; gap: 1px;
  padding: 10px 14px; margin: 0 0 10px;
  background: var(--brand-tint); border-radius: 10px;
  transition: opacity .15s ease;
}
.order-price strong { font-size: 1.6rem; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.order-price span { font-size: .85rem; color: var(--body); }
.order-price.is-quiet { background: var(--bg-alt); }
.order-price.is-quiet strong { font-size: 1.1rem; color: var(--muted); }
.order-price.is-working { opacity: .45; }
.order-note { margin: 8px 0 0; text-align: center; }

/* The weight in the specification box is worked out for the job on the form, so
   it fades the same way the price does while a new one is on its way. */
.spec-list .spec { display: flex; flex-direction: column; gap: 2px; }
.spec-list .spec[hidden] { display: none; }
.spec-list .spec.is-working { opacity: .45; }
.spec-list dd .muted { display: block; }

/* Width and height belong on one line: they are one measurement, and stacking
   them cost the block a whole row it does not have. */
.size-pair { display: flex; align-items: center; gap: 6px; min-width: 0; }
.size-pair input { min-width: 0; text-align: center; }
.size-pair > span { flex: 0 0 auto; font-size: .9rem; }

/* ================================================ cart: artwork, qty, rates */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

ul.tight { margin: .4rem 0 0; padding-left: 1.1rem; }
p.tight { margin: .4rem 0 0; }
ul.tight li { margin-bottom: .15rem; }

/* Artwork sits under the line it belongs to, and a line still waiting for it
   says so in the one place the member is looking. */
.line-artwork {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: #fbfcfd;
}
.line-artwork.is-missing { border-color: #f0c3b4; background: #fdf6f3; }
.line-artwork p { margin: 0; flex: 1 1 180px; min-width: 0; }
.artwork-have { font-size: .9rem; word-break: break-all; }
.artwork-have span { margin-left: 6px; }

/* The file input itself is unstyleable and ugly in every browser; the label is
   the button and the input rides along inside it. */
.file-swap { position: relative; overflow: hidden; display: inline-block; }
.file-swap input[type="file"] {
  position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer;
}
.file-swap .btn { pointer-events: none; }

/* Artwork saves itself the moment a file is chosen, so the picker and the
   Save button step aside while it uploads. The [hidden] attribute on its own
   is not enough here: the rules above give both a display, which outranks the
   browser's default for [hidden]. */
.line-artwork [hidden] { display: none; }
.artwork-status { font-size: .875rem; color: var(--muted); }

.qty-form { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.qty-form input { width: 92px; text-align: right; padding: 7px 8px; font-size: .9rem; }

.rate-options { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 18px; }
.rate-option {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius);
  cursor: pointer;
}
.rate-option:hover { border-color: var(--brand); }
.rate-option:has(input:checked) { border-color: var(--brand); background: #f4f9fc; }
.rate-name { flex: 1 1 auto; font-size: .95rem; }
.rate-name span { display: block; }
.rate-price { font-weight: 600; white-space: nowrap; }
.rate-basis { margin: 0 0 10px; }

.cart-figures { margin: 18px 0 12px; }
.pay-with { margin-bottom: .4rem; }

.pay-method { margin: 18px 0 14px; }
.pay-method h3 { font-size: 1rem; margin: 0 0 10px; }
.pay-option {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px; border: 1px solid var(--line); border-radius: var(--radius);
  cursor: pointer; margin-bottom: 8px;
}
.pay-option:hover { border-color: var(--brand); }
.pay-option:has(input:checked) { border-color: var(--brand); background: #f4f9fc; }
.pay-option input[type="radio"] {
  margin-top: .2em; width: 17px; height: 17px; accent-color: var(--brand); flex: none;
}
.pay-name { display: flex; flex-direction: column; gap: 3px; }
#new-card-fields {
  margin: 2px 0 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
}
#card-container { margin-top: 6px; }

.doc-download {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px; margin: 0 0 18px;
  border: 1px solid var(--line); border-radius: var(--radius); background: #f4f9fc;
}
.doc-download-text { display: flex; flex-direction: column; gap: 3px; }
.doc-download .btn { flex: none; }
@media (max-width: 560px) {
  .doc-download { flex-direction: column; align-items: flex-start; }
}

/* ------------------------------------------------------------ admin: emails */

.admin-head-actions { flex: 0 0 auto; }

.email-editor { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 20px; }
.email-editor textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85rem; line-height: 1.55; }

.email-preview {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 18px; background: #fbfcfd; margin-bottom: 1.4rem;
}
.email-preview-subject { margin: 0 0 10px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.email-preview pre {
  margin: 0; white-space: pre-wrap; word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .82rem; line-height: 1.6; color: var(--ink);
}
.tight-table td { padding: 6px 10px; font-size: .85rem; }
.tight-table code { font-size: .82rem; }

@media (max-width: 900px) {
  .email-editor { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  .cart-line-price { text-align: left; }
  .qty-form { justify-content: flex-start; }
  .rate-option { flex-wrap: wrap; }
}

.ship-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 22px; }
.ship-grid h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 0 0 .5rem; }
.ship-grid .spec-list { grid-template-columns: 1fr; gap: 6px; }
.ship-address { margin: 0; font-size: .95rem; line-height: 1.6; }


/* ---------------------------------------------- a customer's own order */

/* The stages a job goes through, as a ladder rather than a word. A customer
   asking "where is my order" wants to see how far along it is, not to decode
   the word "finishing". */
.order-track { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 2px; }
.track-step {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: 8px;
}
.track-step + .track-step { border-top: 1px solid var(--line); }
.track-dot {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 999px;
  display: grid; place-items: center; font-size: .78rem; font-weight: 700;
  background: var(--bg-alt); color: var(--muted); border: 1px solid var(--line);
}
.track-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.track-now {
  margin-left: auto; flex: 0 0 auto; font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--brand);
}
.track-step.is-done .track-dot { background: #eaf6ee; color: #1e6236; border-color: #b6ddc3; }
.track-step.is-now { background: var(--bg-alt); }
.track-step.is-now .track-dot { background: var(--brand); color: #fff; border-color: var(--brand); }
.track-step.is-todo .track-text strong { color: var(--muted); font-weight: 600; }

/* A line of the order, with the picture of what was sent beside it. */
.order-line { display: flex; gap: 20px; flex-wrap: wrap; padding: 18px 0; }
.order-line + .order-line { border-top: 1px solid var(--line); }
.order-line-art { flex: 0 0 200px; max-width: 100%; }
.order-line-body { flex: 1 1 300px; min-width: 0; }
.order-line-body h3 { font-size: 1rem; margin-bottom: 10px; }
.line-total { margin-top: 10px; font-size: 1.1rem; }

/* The artwork thumbnail. A checkerboard behind it, because print artwork is
   very often white on transparent and would otherwise look like nothing at all. */
.art-thumb {
  display: block; width: 100%; height: auto; border: 1px solid var(--line);
  border-radius: 8px; background-color: #fff;
  background-image:
    linear-gradient(45deg, #f0f1f2 25%, transparent 25%, transparent 75%, #f0f1f2 75%),
    linear-gradient(45deg, #f0f1f2 25%, transparent 25%, transparent 75%, #f0f1f2 75%);
  background-size: 16px 16px;
  background-position: 0 0, 8px 8px;
}
.art-thumb-sm { max-width: 120px; }

/* The thumbnail sits beside the filename in the cart, and above the spec list
   on an admin line. Both want it out of the text flow. */
.artwork-peek { display: block; flex: 0 0 auto; margin: 0 0 8px; }
.line-body .artwork-peek { float: right; margin: 12px 0 12px 16px; }

/* ------------------------------------------- our postage or the member's */

.is-hidden { display: none !important; }
.ship-method { margin-bottom: 18px; }
.ship-method h3 { font-size: .95rem; margin-bottom: 8px; }
.label-panel { margin-top: 10px; padding: 12px 14px; background: var(--bg-alt); border-radius: 8px; }
.label-list { list-style: none; margin: 8px 0; padding: 0; display: grid; gap: 6px; }
.label-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.label-add { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* The carton panel at checkout — box by box, the sizes and weights a member
   copies onto their own carrier's labels. Its own panel rather than a fold-away,
   because someone writing labels needs it in front of them. */
.carton-table { font-size: .88rem; min-width: 560px; }
.carton-table tfoot td { border-top: 2px solid var(--line); border-bottom: 0; }

/* The look-before-you-add preview on a product page. */
.artwork-preview { margin-top: 10px; }
.artwork-preview img { margin-bottom: 6px; }

/* ------------------------------------------ the customer's artwork proof */

/* The three lines are the whole point of this screen, so they are the only
   saturated colour on it: dashed red for the bleed the artwork has to reach,
   solid red for the cut, dashed green for the margin type stays inside. They
   live over a picture of the PDF and never touch the PDF itself. */
/* Jumped to from the contact card. The page is long enough that landing on the
   right section without being told so reads as nothing having happened. */
#edit-details:target {
  outline: 2px solid var(--brand); outline-offset: 4px; border-radius: var(--radius);
}

.proof-dialog {
  width: min(880px, 94vw); max-height: 92vh; padding: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); color: var(--ink);
  overflow: auto;
}
.proof-dialog::backdrop { background: rgba(10, 26, 38, .55); }
.proof-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 18px 20px 12px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg); z-index: 1;
}
.proof-head h2 { font-size: 1.15rem; margin: 0 0 4px; }
.proof-head p { margin: 0; }
.proof-x {
  border: 0; background: none; font-size: 1.6rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 0 4px;
}
.proof-x:hover { color: var(--ink); }
.proof-choice, .proof-pages, .proof-key, .proof-error { margin: 16px 20px; }
.proof-choice p { margin-bottom: 10px; }

/* Resizing their own file. One scale for the whole line, because a job is one
   job — a front at 100% and a back at 104% is two different cards. */
.proof-zoom {
  margin: 16px 20px; padding: 12px 14px;
  background: var(--bg-alt); border: 1px solid var(--line); border-radius: 8px;
}
.zoom-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.zoom-value {
  min-width: 68px; text-align: center; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.zoom-note { margin: 8px 0 0; }

.proof-page { margin: 0 0 22px; }
.proof-page figcaption { font-size: .85rem; color: var(--body); margin-bottom: 8px; }
.proof-page-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* The stage is the drawing surface: the file's own page sits centred on it at
   the size the PDF says it is, which is where the imposition will put it. The
   grey is everything that is not the file. */
.proof-stage {
  position: relative; width: 100%; max-width: 420px;
  background: #eef2f5; border-radius: 4px; overflow: hidden;
}
/* The window the page hangs in: the bleed box, and nothing outside it. The
   press clips artwork to this box, so the proof does too — a customer who sends
   an oversized file sees it arrive as short as it really will. */
/* No background of its own: where the customer's page does not reach, the grey
   of the stage shows through, so an undersized file reads as a gap rather than
   as white artwork on white paper. */
.proof-window { position: absolute; overflow: hidden; }
/* `max-width: none` is load-bearing. The site-wide `img { max-width: 100% }` a
   few hundred lines up clamps any image to its container, and this one is
   deliberately allowed to be bigger than its container: a page enlarged past
   the bleed box is drawn overhanging on all four sides and the window crops it.
   With the clamp in force the width stopped at 100% while the negative offset
   that centres it stayed, so enlarging shoved the page to the left instead of
   growing it from the middle. */
.proof-art {
  position: absolute; display: block; background: #fff;
  max-width: none; max-height: none;
}
.proof-rect { position: absolute; box-sizing: border-box; pointer-events: none; }
.proof-bleed { border: 1.5px dashed #d2402c; }
.proof-cut { border: 1.5px solid #d2402c; }
.proof-safe { border: 1.5px dashed #1e6236; }

.proof-warn {
  margin: 10px 0 0; padding: 8px 10px; font-size: .86rem;
  background: #fdf1e7; border: 1px solid #f2cfae; border-radius: 6px; color: #96491a;
}

.proof-key { list-style: none; padding: 0; display: grid; gap: 6px; font-size: .86rem; }
.proof-key li { display: flex; align-items: center; gap: 10px; color: var(--body); }
.proof-key li::before { content: ""; width: 26px; flex: 0 0 26px; height: 0; }
.proof-key .key-bleed::before { border-top: 2px dashed #d2402c; }
.proof-key .key-cut::before { border-top: 2px solid #d2402c; }
.proof-key .key-safe::before { border-top: 2px dashed #1e6236; }

.proof-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px; padding: 14px 20px; border-top: 1px solid var(--line);
  position: sticky; bottom: 0; background: var(--bg);
}
.proof-foot p { margin: 0; }
.proof-open { margin-bottom: 8px; }

/* The way to the file-setup guide, under the upload field and on a cart line
   still waiting for one. A line of text, because the guide itself is a PDF now:
   the panel this replaced pushed the upload it was explaining off the screen. */
.artwork-guide { margin: 2px 0 8px; }
.artwork-guide a { font-weight: 600; }

/* The per-line stage control, above that line's four downloads. */
.line-stage { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0 10px; }
.line-stage select { width: auto; }

/* The orders list reads as one line per order, so every cell sits on that line.
   The customer cell is two lines deep (company over email) and was dragging the
   rest of the row to its top edge. */
.orders-table th, .orders-table td { vertical-align: middle; }

/* The tracking link on a customer's own order. */
.tracking { margin: 8px 0; font-weight: 600; }

/* The parcel editor on an admin order: narrow numeric cells, all on one line. */
.parcel-table { min-width: 520px; }
.parcel-table th, .parcel-table td { vertical-align: middle; }
.parcel-table td input { min-width: 70px; }

/* The "correct this address" fold on an admin order. */
.edit-address { margin-top: 10px; }
.edit-address > summary { cursor: pointer; font-size: .88rem; color: var(--brand); padding: 4px 0; }
.edit-address .stack-form { margin-top: 10px; }

/* Once fit-columns.js has sized every box to its column's longest value, the
   fixed column widths above step aside: each cell shrinks to its box (or its
   heading, when that is wider) and the table stops stretching to fill the
   panel, so no column is handed slack the values do not need. */
.sheet-table.is-fitted { min-width: 0; width: auto; }
.sheet-table.is-fitted th, .sheet-table.is-fitted td { width: auto; min-width: 0; }
.sheet-table.is-fitted th:last-child, .sheet-table.is-fitted td:last-child { width: 1%; }
.sheet-table.is-fitted td input:not([type="checkbox"]), .sheet-table.is-fitted td select { min-width: 0; max-width: none; }
.sheet-table.is-fitted td .input-prefix { display: inline-flex; width: auto; }

/* What is in each carton, under its box name, when the cart is packed as one. */
.carton-contents { display: block; margin-top: 2px; }


/* Optional artwork design, the customer's brief and proof approval. */
[data-artwork-upload][hidden], [data-design-brief][hidden], [data-design-reference-upload][hidden], [data-upload-proof-note][hidden] { display: none !important; }
.design-service-card, .design-proof-panel {
  margin-top: 16px; padding: 18px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg);
}
.design-proof-panel h4 { margin: 0 0 12px; font-size: 1.05rem; }
.design-brief { margin: 12px 0; }
.design-brief > summary { cursor: pointer; font-weight: 600; }
.design-references { margin-top: 16px; }
.design-reference-list { margin: 8px 0; padding-left: 20px; }
.design-reference-list a { overflow-wrap: anywhere; }
.design-brief .prewrap { overflow-wrap: anywhere; }
.design-proof-preview { display: inline-block; margin-top: 12px; }
.design-proof-preview img { display: block; max-width: 100%; max-height: 260px; object-fit: contain; border: 1px solid var(--line); border-radius: 6px; }
.design-proof-actions { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.design-proof-actions .stack-form { margin-top: 12px; }
.design-proof-actions .check-row { align-items: flex-start; }
.design-proof-panel .prewrap, .design-service-card .prewrap { white-space: pre-wrap; }
.design-proof-panel p:last-child, .design-service-card p:last-child { margin-bottom: 0; }
