/* Calibri, with fallbacks for machines that do not ship it.
   Carlito is the metric-compatible open clone, so a Linux or Android viewer
   gets the same line lengths rather than a reflowed layout; Segoe UI and
   Candara are the nearest stand-ins after that.

   The three webfont rules that used to sit here pointed at .woff2 files that
   were never added to assets/fonts, so every visitor was already falling
   through to Arial. Calibri needs no files at all. */

:root {
  font-family: Calibri, Carlito, "Segoe UI", Candara, "Trebuchet MS", sans-serif;
  color: #171513;
  background: #f2f0ec;
  font-synthesis: none;
  --ink: #171513;
  --muted: #6f6a64;
  --paper: #fcfbf8;
  --canvas: #f2f0ec;
  --accent: #d94c72;
  --accent-deep: #b93059;
  --line: #d9d4cd;
  --ease: cubic-bezier(.22, 1, .36, 1);
  /* The tint sticky table headers sit on. #reporting-table already referenced
     this, but it was never declared, so that header resolved to transparent and
     rows scrolled visibly through it. */
  --surface: #f5f3f0;
}

html {
  /* Stops iOS Safari inflating text when a phone is turned to landscape, which
     silently breaks every width this stylesheet calculates. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: hidden;
  background:
    radial-gradient(circle at 8% 8%, rgba(217, 76, 114, .075), transparent 27rem),
    linear-gradient(135deg, #f6f4f0 0%, var(--canvas) 52%, #ebe7e1 100%);
}

body.is-authenticated { background: #f4f2ee; }
body.is-authenticated .shell { display: none; }

/* A restored session paints straight into the dashboard - no sign-in flash and no
   re-entry animation, so a reload does not read as an automatic sign-out/sign-in.
   The sign-in transition is preserved for an actual sign-in (no session-restored class). */
html.session-restored body { background: #f4f2ee; }
html.session-restored .shell { display: none; }
html.session-restored .dashboard { display: grid; animation: none; }

button, input { font: inherit; }
button { -webkit-tap-highlight-color: transparent; }

.shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: clamp(20px, 5vw, 72px);
}

.auth-surface {
  width: min(100%, 990px);
  min-height: 610px;
  display: grid;
  /* The tracks keep their 0.9:1.1 ratio but are allowed to compress. With hard
     330px/420px minimums the card demanded 750px, which is more than the padded
     shell offers between the 760px stacking breakpoint and roughly 830px, so the
     panels overflowed the card and body overflow-x:hidden clipped them. */
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  overflow: hidden;
  background: var(--paper);
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(43, 36, 30, .14), 0 8px 24px rgba(43, 36, 30, .08);
}

.brand-panel {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(32px, 5vw, 60px);
  overflow: hidden;
  color: #fffaf6;
  background: #201d1b;
}

.brand-panel::after {
  content: "";
  position: absolute;
  z-index: -1;
  right: -105px;
  bottom: 75px;
  width: 330px;
  height: 118px;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 50%;
  transform: rotate(-28deg);
  box-shadow: 0 0 0 34px rgba(255,255,255,.025), 0 0 0 68px rgba(255,255,255,.018);
}

.brand-lockup { display: grid; grid-template-columns: minmax(0, 222px) 14px 92px; align-items: center; gap: 12px; width: min(100%, 352px); }
.brand-lockup img { display: block; width: 100%; height: auto; object-fit: contain; }
.brand-lockup .yes-logo { filter: drop-shadow(0 3px 8px rgba(0,0,0,.16)); }
.shein-crop { position: relative; display: block; width: 92px; height: 30px; overflow: hidden; }
.brand-lockup .shein-logo { position: absolute; top: -10px; left: 0; width: 92px; max-width: none; filter: invert(1); }
.brand-lockup span { color: var(--accent); font-size: 1rem; font-weight: 600; text-align: center; }
.edition, .step-label { margin: 0 0 22px; font-size: .76rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.edition { color: #c9c1b9; }
.brand-copy h1 { max-width: none; margin: 0; font-size: 3.15rem; line-height: .98; letter-spacing: 0; }
.brand-copy .title-line { display: block; color: #fffaf6; white-space: nowrap; }
.brand-copy .title-partner { margin-top: 5px; }
.brand-copy .title-line b { color: var(--accent); font-weight: 400; }
.brand-note { max-width: 28ch; margin: 24px 0 0; color: #c9c1b9; font-size: .96rem; line-height: 1.55; }
.folio-meta { display: flex; justify-content: space-between; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.15); color: #9f9790; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; }

.task-panel { position: relative; display: grid; place-items: center; padding: clamp(34px, 7vw, 80px); }
.view { grid-area: 1 / 1; width: min(100%, 390px); transition: opacity .42s var(--ease), transform .5s var(--ease), filter .42s var(--ease); }
.view:not(.is-active) { pointer-events: none; opacity: 0; transform: translateY(16px) scale(.985); filter: blur(5px); }
.view-header { margin-bottom: 34px; }
.step-label { color: var(--muted); }
.step-label span { color: var(--accent-deep); margin-right: 10px; }
h2 { margin: 0; font-size: clamp(2.1rem, 4vw, 3.15rem); line-height: 1; letter-spacing: -.035em; }
.view-header > p:last-child, .view-auth > p:not(.step-label):not(.upload-status) { margin: 15px 0 0; color: var(--muted); line-height: 1.55; }

form { display: grid; gap: 16px; }
.field { position: relative; }
.field label { position: absolute; z-index: 1; top: 9px; left: 16px; color: var(--muted); font-size: .7rem; font-weight: 600; letter-spacing: .045em; text-transform: uppercase; pointer-events: none; transition: color .2s ease; }
.field input { width: 100%; height: 62px; padding: 25px 52px 9px 16px; color: var(--ink); font-size: .95rem; font-weight: 400; background: #fff; border: 1px solid var(--line); border-radius: 12px; outline: 0; transition: border-color .2s ease, box-shadow .2s ease, background .2s ease; }
.field:focus-within label { color: var(--accent-deep); }
.field input:hover { border-color: #b6afa6; }
.field input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(217, 76, 114, .12); background: #fffdfc; }
.password-wrap { position: relative; }
.reveal { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); padding: 8px; color: var(--muted); font-size: .76rem; font-weight: 600; background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
.reveal:hover { color: var(--accent-deep); background: rgba(217,76,114,.07); }
.reveal:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.form-error { min-height: 0; margin: -4px 2px 0; color: #a1223f; font-size: .8rem; }
.form-error:not(:empty) { min-height: 20px; }

.primary-button {
  width: 100%; min-height: 56px; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 18px 14px 22px;
  color: #fff; font-weight: 700; background: linear-gradient(135deg, var(--accent), #c83d65); border: 0; border-radius: 12px; cursor: pointer;
  box-shadow: 0 10px 24px rgba(185, 48, 89, .22), 0 3px 8px rgba(90, 26, 45, .12);
  transition: transform .24s var(--ease), box-shadow .24s ease, background .24s ease;
}
.primary-button svg { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.primary-button:hover { transform: translateY(-2px); background: linear-gradient(135deg, #e2547b, var(--accent-deep)); box-shadow: 0 16px 30px rgba(185,48,89,.28), 0 5px 10px rgba(90,26,45,.14); }
.primary-button:active { transform: translateY(1px); box-shadow: 0 5px 12px rgba(185,48,89,.2); }
.primary-button:focus-visible { outline: 3px solid rgba(217,76,114,.28); outline-offset: 4px; }
.primary-button:disabled { cursor: wait; opacity: .72; transform: none; }

.view-auth { text-align: left; }
.success-mark { width: 54px; height: 54px; display: grid; place-items: center; margin: 0 auto 34px; color: var(--accent-deep); background: rgba(217,76,114,.1); border-radius: 50%; }
.success-mark svg { width: 27px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.upload-button { justify-content: center; margin-top: 36px; min-height: 64px; }
.upload-status { min-height: 24px; margin: 14px 0 0; color: var(--accent-deep); font-size: .85rem; text-align: center; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

.dashboard { min-height: 100dvh; display: none; grid-template-columns: 248px minmax(0, 1fr); overflow-x: hidden; background: #f4f2ee; }
.dashboard.is-active { display: grid; animation: dashboard-in .42s var(--ease) both; }
@keyframes dashboard-in { from { opacity: 0; clip-path: inset(2% 2% 2% 2% round 16px); } to { opacity: 1; clip-path: inset(0); } }
.dashboard.is-manifest-view { grid-template-columns: minmax(0, 1fr); height: 100dvh; overflow: hidden; }
.dashboard.is-manifest-view .sidebar { display: none; }
.dashboard.is-manifest-view .dashboard-header { display: none; }
.dashboard.is-manifest-view .workspace { display: none; }
.dashboard.is-manifest-view .recent { display: none; }
/* overflow-y keeps the six nav items and the account block reachable on a short
   viewport - a landscape phone is under 400px tall, which is less than the column
   needs, and without this the bottom of the sidebar was simply cut off. */
.sidebar { position: fixed; inset: 0 auto 0 0; z-index: 10; width: 248px; min-height: 100vh; height: 100dvh; display: flex; flex-direction: column; padding: 34px 22px 22px; overflow-y: auto; color: #fffaf6; background: #201d1b; }
.sidebar-brand { display: grid; grid-template-columns: minmax(0, 1fr) 10px 52px; align-items: center; gap: 7px; width: 100%; margin: 0 0 54px; color: inherit; text-decoration: none; }
.sidebar-brand img { display: block; width: 100%; height: auto; object-fit: contain; }
.sidebar-brand span { color: var(--accent); font-size: .8rem; text-align: center; }
.sidebar-shein-crop { position: relative; display: block; width: 52px; height: 18px; overflow: hidden; }
.sidebar-shein-logo { position: absolute; top: -5px; left: 0; width: 52px !important; max-width: none; filter: invert(1); }
.sidebar-nav { display: grid; gap: 6px; }
.nav-item { display: flex; align-items: center; gap: 13px; min-height: 48px; padding: 0 14px; color: #aaa29a; font-size: .9rem; font-weight: 600; text-decoration: none; border-radius: 10px; transition: color .18s ease, background .18s ease; }
.nav-item svg { width: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.nav-item:hover { color: #fff; background: rgba(255,255,255,.055); }
.nav-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nav-item.is-current { color: #fff; background: rgba(255,255,255,.09); }
.sidebar-account { display: grid; grid-template-columns: 38px 1fr 34px; gap: 10px; align-items: center; margin-top: auto; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.12); }
.account-avatar { width: 38px; height: 38px; display: grid; place-items: center; color: #201d1b; background: #f3d8df; border-radius: 50%; font-size: .7rem; font-weight: 700; }
.sidebar-account strong, .sidebar-account span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-account strong { color: #fff; font-size: .76rem; }
.sidebar-account span { margin-top: 3px; color: #8f8882; font-size: .68rem; }
.icon-button { width: 34px; height: 34px; display: grid; place-items: center; color: #aaa29a; background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
.icon-button:hover { color: #fff; background: rgba(255,255,255,.08); }
.icon-button:focus-visible { outline: 2px solid var(--accent); }
.icon-button svg { width: 19px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

.dashboard-main { min-width: 0; width: 100%; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dashboard.is-manifest-view .dashboard-main { grid-column: 1; min-height: 0; height: 100dvh; gap: 0; overflow: hidden; padding: 10px clamp(10px, 1.5vw, 20px) 10px; }
.dashboard:not(.is-manifest-view) .dashboard-main { grid-column: 2; max-width: 1320px; margin: 0 auto; padding: 48px clamp(28px, 5vw, 72px) 64px; }
.dashboard-header { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 32px; margin-bottom: 46px; }
.dashboard.is-manifest-view .dashboard-header { align-items: center; margin: 0; padding: 0; }
.dashboard.is-manifest-view .dashboard-header h1 { font-size: 2.1rem; }
.dashboard.is-manifest-view .dashboard-header > div > p:last-child { margin-top: 8px; }
.dashboard-kicker, .section-label { margin: 0 0 10px; color: var(--accent-deep); font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.dashboard-header h1 { margin: 0; font-size: 2.55rem; line-height: 1; letter-spacing: -.035em; }
.dashboard-header > div > p:last-child { margin: 12px 0 0; color: var(--muted); }
.dashboard-upload { min-height: 52px; display: flex; align-items: center; gap: 10px; padding: 0 20px; color: #fff; font-weight: 700; background: var(--accent); border: 0; border-radius: 12px; box-shadow: 0 10px 22px rgba(185,48,89,.2); cursor: pointer; transition: transform .2s var(--ease), box-shadow .2s ease, background .2s ease; }
.dashboard-upload svg { width: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dashboard-upload:hover { transform: translateY(-2px); background: var(--accent-deep); box-shadow: 0 15px 28px rgba(185,48,89,.26); }
.dashboard-upload:active { transform: translateY(0); }
.dashboard-upload:focus-visible, .dropzone:focus-visible, .text-action:focus-visible { outline: 3px solid rgba(217,76,114,.25); outline-offset: 3px; }

.workspace { overflow: hidden; background: var(--paper); border-radius: 16px; box-shadow: 0 18px 50px rgba(43,36,30,.09), 0 4px 14px rgba(43,36,30,.05); }
.dashboard.is-manifest-view .workspace { display: none; }
.workspace-heading { display: flex; justify-content: space-between; align-items: center; gap: 24px; padding: 28px 32px 24px; border-bottom: 1px solid var(--line); }
.workspace-heading h2, .recent-heading h2 { margin: 0; font-size: 1.35rem; letter-spacing: -.02em; }
.status-chip { display: inline-flex; align-items: center; gap: 8px; color: #4e6d59; font-size: .76rem; font-weight: 600; }
.status-chip i { width: 7px; height: 7px; background: #5f8d6c; border-radius: 50%; box-shadow: 0 0 0 4px rgba(95,141,108,.13); }
.manifest-grid { display: grid; grid-template-columns: .85fr 1.15fr; min-height: 330px; }
.manifest-intro { padding: 44px 36px; background: #f8f6f2; }
.manifest-number { margin: 0 0 48px; color: #bcb4ac; font-size: .76rem; font-weight: 700; }
.manifest-intro h3 { max-width: 13ch; margin: 0; font-size: 1.8rem; line-height: 1.08; letter-spacing: -.03em; }
.manifest-intro > p:not(.manifest-number) { max-width: 38ch; margin: 16px 0 24px; color: var(--muted); font-size: .9rem; line-height: 1.6; }
.text-action { display: flex; align-items: center; gap: 9px; padding: 0; color: var(--accent-deep); font-weight: 700; background: transparent; border: 0; cursor: pointer; }
.text-action span { transition: transform .18s ease; }
.text-action:hover span { transform: translateX(4px); }
.dropzone { align-self: stretch; margin: 28px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; color: var(--muted); background: #fff; border: 1px dashed #c9c1b9; border-radius: 14px; cursor: pointer; transition: border-color .2s ease, background .2s ease, transform .2s var(--ease); }
.dropzone:hover, .dropzone.is-dragging { color: var(--accent-deep); background: #fff9fa; border-color: var(--accent); transform: translateY(-2px); }
.drop-icon { width: 52px; height: 52px; display: grid; place-items: center; margin-bottom: 18px; color: var(--accent-deep); background: #fae9ee; border-radius: 12px; }
.drop-icon svg, .file-glyph svg { width: 25px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.dropzone strong { color: var(--ink); font-size: 1rem; }
.dropzone > span:last-child { margin-top: 8px; font-size: .78rem; }
.dashboard-status { min-height: 0; margin: 0; padding: 0 32px; color: var(--accent-deep); font-size: .84rem; }
.dashboard-status:not(:empty) { min-height: 42px; padding-top: 13px; border-top: 1px solid var(--line); }

.manifest-workbench { margin: 0; min-height: 0; overflow: hidden; background: var(--paper); border-radius: 0; box-shadow: none; flex: 1; display: flex; flex-direction: column; }
.dashboard.is-manifest-view .manifest-workbench { border-radius: 16px; box-shadow: 0 16px 44px rgba(43,36,30,.08), 0 4px 12px rgba(43,36,30,.045); }
.dashboard:not(.is-manifest-view) .manifest-workbench { margin-top: 28px; border-radius: 16px; box-shadow: 0 16px 44px rgba(43,36,30,.08), 0 4px 12px rgba(43,36,30,.045); }
.workbench-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 22px; padding: 14px 20px; border-bottom: 1px solid var(--line); flex-shrink: 0; background: var(--paper); }
.workbench-toolbar-left { display: flex; align-items: center; gap: 16px; min-width: 0; }
.workbench-toolbar h2 { margin: 0; font-size: 1.1rem; letter-spacing: 0; }
.back-button { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px 7px 10px; color: var(--muted); font-size: .78rem; font-weight: 600; background: transparent; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; transition: color .18s ease, border-color .18s ease, background .18s ease, transform .18s var(--ease); }
.back-button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.back-button:hover { color: var(--accent-deep); border-color: #c9c1b9; background: #fff9fa; transform: translateX(-2px); }
.back-button:focus-visible { outline: 3px solid rgba(217,76,114,.24); outline-offset: 2px; }
.toolbar-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.calculate-button { min-height: 38px; display: inline-flex; align-items: center; justify-content: center; padding: 0 16px; color: #fff; font-size: .76rem; font-weight: 700; background: var(--accent-deep); border: 1px solid var(--accent-deep); border-radius: 10px; cursor: pointer; transition: transform .18s var(--ease), background .18s ease, opacity .18s ease; }
.calculate-button:hover:not(:disabled) { transform: translateY(-1px); background: var(--accent); border-color: var(--accent); }
.calculate-button:active:not(:disabled) { transform: translateY(0); }
.calculate-button:focus-visible { outline: 3px solid rgba(217,76,114,.24); outline-offset: 2px; }
.calculate-button:disabled { color: var(--muted); background: #efede9; border-color: var(--line); cursor: not-allowed; opacity: .78; }
.secondary-button, .column-enrich { min-height: 38px; display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 0 13px; color: var(--ink); font-size: .76rem; font-weight: 700; background: #fff; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; transition: transform .18s var(--ease), border-color .18s ease, color .18s ease, box-shadow .18s ease; }
.secondary-button:hover, .column-enrich:hover { transform: translateY(-1px); color: var(--accent-deep); border-color: #c9c1b9; box-shadow: 0 8px 18px rgba(43,36,30,.08); }
.secondary-button:active, .column-enrich:active { transform: translateY(0); }
.secondary-button:focus-visible, .column-enrich:focus-visible, .sheet-cell-input:focus-visible { outline: 3px solid rgba(217,76,114,.24); outline-offset: 2px; }
.secondary-button:disabled, .column-enrich:disabled { cursor: wait; opacity: .64; transform: none; box-shadow: none; }
.sheet-summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-bottom: 1px solid var(--line); background: #f8f6f2; flex-shrink: 0; }
.sheet-summary div { min-width: 0; padding: 18px 28px; border-right: 1px solid var(--line); }
.sheet-summary div:last-child { border-right: 0; }
.sheet-summary span { display: block; overflow: hidden; color: var(--ink); font-size: 1.35rem; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.sheet-summary strong { display: block; margin-top: 5px; color: var(--muted); font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.sheet-status { min-height: 0; margin: 0; padding: 0 28px; color: var(--muted); font-size: .82rem; line-height: 1.45; flex-shrink: 0; }
.sheet-status:not(:empty) { min-height: 42px; padding-top: 13px; border-bottom: 1px solid var(--line); }
.table-shell { min-height: 0; overflow: auto; flex: 1; overscroll-behavior: contain; background: #fff; }

/* ==========================================================================
   Shared table chrome
   Every table in the app sits inside a .table-shell, so the shell is what
   carries the look they have in common: the sticky uppercase header, the cell
   padding, the row rule and the hover tint. This used to be written out per
   table id, which left the seven Manifest Builder tables - none of them on
   that list - rendering as bare browser defaults: no padding, no rules, and
   columns running straight into one another.
   The per-table rules further down override by id, so a table that needs its
   own widths, wrapping or alignment still gets them.
   ========================================================================== */
.table-shell > table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  color: var(--ink);
  font-size: .8rem;
  font-weight: 500;
  text-align: left;
}
.table-shell > table > thead > tr > th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 13px 16px;
  color: #4a4440;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-align: left;
  text-transform: uppercase;
  /* Headings are two or three words; wrapping them only makes the header
     taller than the rows it labels. */
  white-space: nowrap;
  background: #f5f3f0;
  border-bottom: 1px solid var(--line);
}
.table-shell > table > tbody > tr > td,
.table-shell > table > tfoot > tr > td {
  padding: 13px 16px;
  vertical-align: middle;
  border-bottom: 1px solid #ebe7e1;
  /* AWBs, account numbers, file names and email addresses are each one
     unbroken token, so wrapping has to be allowed to break inside the word -
     normal wrapping only breaks at spaces and would overflow the column. */
  overflow-wrap: anywhere;
}
/* The shell is clipped by the rounded card around it, so a rule under the last
   row would only ever sit on top of the card edge. */
.table-shell > table > tbody > tr:last-child > td { border-bottom: 0; }
/* The manifest sheet is left out: its frozen first column and its calculated
   cells carry their own backgrounds, so a row tint would only half apply. */
.table-shell > table:not(#manifest-table) > tbody > tr:hover { background: #fff8fa; }

/* Figures line up under one another and never break across two lines. */
.table-shell > table .is-number,
.table-shell > table .is-money {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
/* A date is short and reads badly split over two lines. */
.table-shell > table .is-date { white-space: nowrap; }
/* The single row a table shows when it has nothing to list. It spans every
   column, so the per-table width ceilings have to come off it. */
.table-shell > table .is-empty-state {
  max-width: none;
  padding: 30px 16px;
  color: var(--muted);
  text-align: center;
  border-right: 0;
}

.table-save-bar { display: flex; align-items: center; justify-content: flex-end; gap: 18px; padding: 16px 28px; border-top: 1px solid var(--line); background: var(--paper); flex-shrink: 0; }
.table-save-bar span { margin-right: auto; color: var(--muted); font-size: .76rem; }
.save-data-button { min-height: 42px; padding: 0 20px; color: #fff; font-size: .76rem; font-weight: 700; background: var(--accent-deep); border: 0; border-radius: 10px; cursor: pointer; transition: transform .18s var(--ease), background .18s ease; }
.save-data-button:hover { transform: translateY(-1px); background: var(--accent); }
.save-data-button:active { transform: translateY(0); }
.save-data-button:focus-visible { outline: 3px solid rgba(217,76,114,.24); outline-offset: 2px; }
#manifest-table { width: 100%; min-width: 4770px; table-layout: fixed; border-collapse: separate; border-spacing: 0; color: var(--ink); font-size: .8rem; font-weight: 500; }

/* Column widths.
   table-layout is fixed, so the widths set on the header row decide every
   column. Text columns are sized so their wrapped content stays to a line or
   two; the editable ones are sized to fit their value outright, because an
   <input> cannot wrap and would go back to hiding the end of a MAWB, an account
   number or a traffic code. The sum is what min-width above is set from. */
#manifest-table th[data-column="Original AWB"] { width: 150px; }
#manifest-table th[data-column="F/d"] { width: 100px; }
#manifest-table th[data-column="Bag Number"] { width: 170px; }
#manifest-table th[data-column="Pieces"] { width: 100px; }
#manifest-table th[data-column="Weight Lbs"] { width: 110px; }
#manifest-table th[data-column="Shipper"] { width: 110px; }
#manifest-table th[data-column="Consignee"] { width: 150px; }
#manifest-table th[data-column="Address"] { width: 260px; }
#manifest-table th[data-column="TinNumber"] { width: 120px; }
#manifest-table th[data-column="Flight Date"] { width: 110px; }
#manifest-table th[data-column="Desc"] { width: 130px; }
#manifest-table th[data-column="Description Code"] { width: 160px; }
#manifest-table th[data-column="MAWB"] { width: 165px; }
#manifest-table th[data-column="Account Numbers"] { width: 165px; }
#manifest-table th[data-column="Value"] { width: 110px; }
#manifest-table th[data-column="Traffic Code"] { width: 150px; }
#manifest-table th[data-column="Duty %"] { width: 110px; }
#manifest-table th, #manifest-table td { min-width: 100px; padding: 13px 14px; border-right: 1px solid #ebe7e1; border-bottom: 1px solid #ebe7e1; vertical-align: middle; }
#manifest-table th { position: sticky; top: 0; z-index: 2; color: #4a4440; font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-align: left; text-transform: uppercase; background: #f5f3f0; padding: 14px 14px; resize: horizontal; overflow: hidden; }
.file-row-select { display: flex; align-items: center; justify-content: center; padding-left: 20px; cursor: pointer; }
.manifest-checkbox { width: 18px; height: 18px; cursor: pointer; accent-color: var(--accent); }
#manifest-table th:first-child, #manifest-table td:first-child { position: sticky; left: 0; z-index: 3; min-width: 96px; width: 96px; background: #fffdfc; box-shadow: 1px 0 0 #ebe7e1; }
#manifest-table th:first-child { z-index: 4; background: #f8f6f2; }
.row-action-heading, .row-action-cell { text-align: center !important; background: #f8f6f2 !important; }
.row-enrich-button { min-height: 34px; padding: 0 12px; color: var(--accent-deep); font-size: .76rem; font-weight: 700; background: #fff; border: 1px solid #edd1da; border-radius: 8px; cursor: pointer; transition: color .18s ease, border-color .18s ease, background .18s ease; }
.row-enrich-button:hover { color: #fff; background: var(--accent-deep); border-color: var(--accent-deep); }
.row-enrich-button:focus-visible { outline: 3px solid rgba(217,76,114,.24); outline-offset: 2px; }
.row-enrich-button:disabled { cursor: wait; opacity: .68; }
#manifest-table th span { display: block; white-space: normal; }
/* Cells wrap instead of being cut off with an ellipsis. A bag number or an AWB
   is one long unbroken token, so overflow-wrap has to be allowed to break inside
   the word - normal wrapping only breaks at spaces and would still overflow.
   The cells align to the middle, not the top, because roughly half of them hold
   a 34px <input> whose text is centred inside it: top-aligning the row left the
   typed values sitting about 9px below the plain-text ones beside them. */
#manifest-table td { white-space: normal; overflow-wrap: anywhere; vertical-align: middle; }
#manifest-table td.is-money, #manifest-table td.is-calculated { font-variant-numeric: tabular-nums; text-align: right; }
/* Amounts are short and must never be broken across two lines. */
#manifest-table td.is-money, #manifest-table td.is-calculated, #manifest-table td.row-action-cell { white-space: nowrap; }
#manifest-table td.is-calculated { color: #3f3a35; background: #fdfbf8; }
#manifest-table td.is-empty { color: #b6afa6; }
.column-enrich { width: 100%; min-height: 28px; margin-top: 8px; padding-inline: 8px; color: var(--accent-deep); font-size: .66rem; background: #fff9fa; border-color: #edd1da; }
.sheet-cell-input { width: 100%; min-width: 0; height: 34px; padding: 0 9px; color: var(--ink); font-size: .78rem; background: #fff; border: 1px solid transparent; border-radius: 8px; outline: 0; transition: border-color .18s ease, background .18s ease, box-shadow .18s ease; }
.sheet-cell-input:hover { border-color: #d9d4cd; }
.sheet-cell-input:focus { background: #fffdfc; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(217,76,114,.12); }
#manifest-table td.is-manual-entry { background: #fff9fa; }
#manifest-table td.is-manual-entry .sheet-cell-input { border-color: #edd1da; }
#manifest-table td.is-manual-entry .sheet-cell-input:hover { border-color: var(--accent); }

.recent { margin-top: 28px; background: var(--paper); border-radius: 16px; box-shadow: 0 10px 32px rgba(43,36,30,.065); }
.dashboard.is-manifest-view .recent { display: none; }
.recent-heading { display: flex; justify-content: space-between; align-items: center; padding: 24px 28px; border-bottom: 1px solid var(--line); }
.recent-heading span { color: var(--muted); font-size: .76rem; }
.empty-row { display: flex; align-items: center; gap: 16px; padding: 28px; }
.recent-list { display: grid; }
.file-row { display: grid; grid-template-columns: auto minmax(0, 1fr) 48px; align-items: stretch; border-top: 1px solid #ebe7e1; }
.file-row:first-child { border-top: 0; }
.file-glyph { width: 42px; height: 42px; display: grid; place-items: center; flex: 0 0 auto; color: #8c857e; background: #efede9; border-radius: 10px; }
.empty-row strong, .file-row strong { font-size: .9rem; }
.empty-row p { margin: 5px 0 0; color: var(--muted); font-size: .8rem; }
.file-row-open { min-width: 0; display: flex; align-items: center; gap: 16px; padding: 22px 12px 22px 14px; color: inherit; text-align: left; background: transparent; border: 0; cursor: pointer; transition: background .18s ease; }
.file-row-open:hover { background: #fff8fa; }
.file-row-open:disabled { cursor: wait; opacity: .68; }
.file-row-content { min-width: 0; flex: 1; }
.file-row-name, .file-row-meta { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-row-name { color: var(--accent-deep); }
.file-row-meta { margin-top: 5px; color: var(--muted); font-size: .8rem; }
.file-row-action { flex: 0 0 auto; color: var(--accent-deep); font-size: .76rem; font-weight: 700; opacity: 0; transform: translateX(-5px); transition: opacity .18s ease, transform .18s ease; }
.file-row-open:hover .file-row-action, .file-row-open:focus-visible .file-row-action { opacity: 1; transform: translateX(0); }
.file-row-delete { width: 48px; min-height: 48px; align-self: center; background: transparent; border: none; border-radius: 8px; color: var(--accent-deep); cursor: pointer; font-size: 22px; line-height: 1; transition: color .18s ease, background .18s ease; }
.file-row-delete:hover { color: #a1223f; background: #fae9ee; }
.file-row-open:focus-visible,
.file-row-delete:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 900px) {
  .dashboard { grid-template-columns: 78px minmax(0, 1fr); }
  .dashboard.is-manifest-view { grid-template-columns: minmax(0, 1fr); }
  .sidebar { width: 78px; padding-inline: 14px; }
  .sidebar-brand { display: block; width: 42px; height: 42px; margin-inline: auto; overflow: hidden; }
  .sidebar-yes-logo { width: 294px !important; max-width: none; height: 42px !important; object-fit: contain; object-position: left center; }
  .sidebar-brand > span, .sidebar-shein-crop, .nav-item span, .sidebar-account > div:nth-child(2), .sidebar-account .icon-button { display: none !important; }
  .sidebar-nav { justify-items: center; }
  .nav-item { width: 48px; justify-content: center; padding: 0; }
  .sidebar-account { display: flex; justify-content: center; }
}

@media (max-width: 680px) {
  .dashboard { grid-template-columns: 1fr; }
  .dashboard.is-manifest-view { height: 100dvh; overflow: hidden; }
  .sidebar { position: static; width: 100%; min-height: 68px; height: 68px; flex-direction: row; align-items: center; padding: 10px 18px; }
  .sidebar-brand { margin: 0 auto 0 0; }
  .sidebar-nav { display: flex; }
  .sidebar-account { margin: 0 0 0 10px; padding: 0; border: 0; }
  .dashboard:not(.is-manifest-view) .dashboard-main { grid-column: 1; padding: 32px 18px 40px; }
  .dashboard.is-manifest-view .dashboard-main { height: 100dvh; gap: 12px; padding: 12px; }
  .dashboard-header { grid-template-columns: 1fr; align-items: start; margin-bottom: 30px; }
  .dashboard.is-manifest-view .dashboard-header { gap: 16px; }
  .dashboard.is-manifest-view .dashboard-header h1 { font-size: 1.9rem; }
  .dashboard-header h1 { font-size: 2.15rem; }
  .dashboard-upload { width: 100%; justify-content: center; }
  .workspace-heading { align-items: flex-start; padding: 22px; }
  .status-chip { margin-top: 4px; }
  .manifest-grid { grid-template-columns: 1fr; }
  .manifest-intro { padding: 30px 24px; }
  .manifest-number { margin-bottom: 26px; }
  .dropzone { min-height: 220px; margin: 18px; padding: 28px 16px; }
  .recent-heading { padding: 20px; }
  .file-row-open { padding: 18px 8px 18px 10px; }
  .file-row-action { display: none; }
  .workbench-toolbar { align-items: stretch; flex-direction: column; padding: 22px; }
  .toolbar-actions { justify-content: stretch; }
  .calculate-button, .secondary-button { flex: 1 1 150px; }
  .sheet-summary { grid-template-columns: 1fr; }
  .dashboard.is-manifest-view .sheet-summary { grid-template-columns: repeat(3, minmax(150px, 1fr)); overflow-x: auto; }
  .sheet-summary div { border-right: 0; border-bottom: 1px solid var(--line); padding: 16px 22px; }
  .dashboard.is-manifest-view .sheet-summary div { border-right: 1px solid var(--line); border-bottom: 0; }
  .sheet-summary div:last-child { border-bottom: 0; }
  .sheet-status { padding-inline: 22px; }
  .table-shell { max-height: 62vh; }
  .dashboard.is-manifest-view .table-shell { max-height: none; flex: 1; }
  .table-save-bar { align-items: stretch; flex-direction: column; padding: 16px 22px; }
  .save-data-button { width: 100%; }
}

@media (max-width: 760px) {
  .shell { padding: 16px; place-items: start center; }
  .auth-surface { min-height: calc(100dvh - 32px); grid-template-columns: 1fr; }
  .brand-panel { min-height: 230px; padding: 28px; }
  .brand-copy h1 { max-width: none; font-size: 2.65rem; }
  .brand-copy .title-line { white-space: normal; }
  .brand-note, .folio-meta { display: none; }
  .task-panel { min-height: 500px; padding: 38px 26px; }
}

@media (max-width: 760px) and (max-height: 740px) {
  .shell { padding: 10px; }
  .auth-surface { min-height: calc(100dvh - 20px); }
  .brand-panel { min-height: 168px; padding: 22px 26px; }
  .brand-copy h1 { font-size: 2.25rem; }
  .edition { margin-bottom: 12px; }
  .task-panel { min-height: 450px; padding-block: 30px; }
  .view-header { margin-bottom: 24px; }
}

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

/* ---------- Automations Specific Styles ---------- */
.tab-btn {
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  padding: 10px 18px;
  font-size: .85rem;
  font-weight: 700;
  color: var(--muted);
  border-radius: 10px;
  transition: all 0.2s ease;
}
.tab-btn:hover {
  color: var(--ink);
  background: #fff9fa;
}
.tab-btn.is-current {
  color: var(--accent-deep);
  background: #fff;
  border-color: var(--accent);
  box-shadow: 0 4px 12px rgba(43,36,30,.05);
}

.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(23,21,19,.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: grid; place-items: center;
  padding: 24px;
  animation: fade-in .2s ease;
}
.modal-backdrop.hidden {
  display: none !important;
}
.modal-dialog {
  width: 100%; max-width: 400px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(43,36,30,.15);
  padding: 34px 30px;
  text-align: center;
  animation: pop-in .25s var(--ease);
}
@keyframes fade-in { from { opacity: 0; } }
@keyframes pop-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }

/* ---- the console, reporting and report tables --------------------------
   The shared chrome above already gives these their header, their padding and
   their row rule. What is left here is only what sets them apart from it. */

/* These lay out to their content, so without a ceiling one long column takes
   the width and starves the rest. */
#automation-table, #recurring-table, #logs-table, #report-table { table-layout: auto; }
#automation-table td, #recurring-table td, #logs-table td, #report-table td { max-width: 320px; }

/* A rule between the columns, which the dense data tables want and the lighter
   dashboard ones do not. Never after the last column: that line would land on
   the card edge and read as a double border. */
#automation-table th:not(:last-child), #automation-table td:not(:last-child),
#recurring-table th:not(:last-child), #recurring-table td:not(:last-child),
#logs-table th:not(:last-child), #logs-table td:not(:last-child),
#reporting-table th:not(:last-child), #reporting-table td:not(:last-child),
#report-table th:not(:last-child), #report-table td:not(:last-child) {
  border-right: 1px solid #ebe7e1;
}

/* Rows in the console tables can run to more than one line, so their cells
   align to the top rather than to the middle the shared rule sets. */
#automation-table td, #recurring-table td, #logs-table td { vertical-align: top; }

/* The one table whose first column is frozen: its rows are wide enough that
   the name would otherwise scroll out of sight. */
#automation-table th:first-child, #automation-table td:first-child {
  position: sticky; left: 0; z-index: 3; background: #fffdfc; box-shadow: 1px 0 0 #ebe7e1;
}
#automation-table th:first-child { z-index: 4; background: #f8f6f2; }

/* ---- Reporting: the sheet picker ----
   Four columns on a fixed layout. Left to size themselves they split evenly,
   which handed a third of the table to Rows - never more than three digits -
   and squeezed the file name, the one column anyone actually reads, into the
   same third. */
#reporting-table { table-layout: fixed; }
#reporting-table th:nth-child(2) { width: auto; }
#reporting-table th:nth-child(3) { width: 210px; }
#reporting-table th:nth-child(4) { width: 100px; }
#reporting-table td:nth-child(3) { white-space: nowrap; }
#reporting-table th:nth-child(4), #reporting-table td:nth-child(4) { text-align: right; }
#reporting-table td:nth-child(4) { font-variant-numeric: tabular-nums; }
#reporting-table th.col-check, #reporting-table td.col-check {
  width: 58px;
  padding-inline: 10px;
  text-align: center;
}

.col-check { width: 48px; text-align: center !important; }
.col-num { width: 56px; color: var(--muted); text-align: center !important; }
input[type=checkbox] { 
  width: 18px; height: 18px; 
  accent-color: var(--accent-deep); 
  cursor: pointer;
  margin: 0;
}
select.automation-status {
  width: 100%;
  padding: 6px 10px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: .78rem;
  color: var(--ink);
  cursor: pointer;
  outline: 0;
  transition: border-color .18s ease, box-shadow .18s ease;
}
select.automation-status:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(217,76,114,.12);
}
tbody tr.selected {
  background: #fff9fa !important;
}
tbody tr.selected td {
  border-bottom-color: #edd1da;
}

/* ==========================================================================
   Toolbar, date filter and settings components
   Previously inline styles in index.html, which no media query could reach.
   The declarations reproduce the desktop look these elements already had.
   ========================================================================== */

.workbench-toolbar.is-wrapping { flex-wrap: wrap; }
.workbench-toolbar-left.is-wrapping { gap: 20px; flex-wrap: wrap; }
.toolbar-actions.is-centered { align-items: center; }
.toolbar-count { margin-right: 16px; font-size: 14px; }
#reporting-title { margin: 0; font-size: 1.1rem; }

.date-range { display: flex; align-items: center; gap: 10px; }
.date-range-sep { flex: 0 0 auto; color: var(--muted); font-size: .8rem; font-weight: 600; }
/* width:auto rather than the 100% .sheet-cell-input gives a date field, and
   min-width:0 so it can still shrink inside the flex row. */
.date-input { width: auto; min-width: 0; height: 38px; padding: 6px 12px; }

.settings-card { max-width: 600px; padding: 30px; background: #fff; border: 1px solid var(--line); border-radius: 12px; }
#settings-title { margin: 0 0 24px; font-size: 1.2rem; }
.settings-avatar-row { display: flex; align-items: center; gap: 20px; margin-bottom: 24px; }
/* script.js assigns style.backgroundImage here, so the sizing the inline style
   used to carry has to live in the stylesheet or the avatar renders untiled. */
.account-avatar.settings-avatar { width: 80px; height: 80px; font-size: 1.5rem; }
.account-avatar { background-size: cover; background-position: center; }
.settings-field { margin-bottom: 20px; }
.settings-field .section-label { display: block; margin: 0 0 8px; }
.settings-input { width: 100%; height: 44px; padding: 10px 14px; font-size: 1rem; }
.settings-input.is-readonly { color: var(--muted); background: #f9f8f6; cursor: not-allowed; }
.settings-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 16px; margin-top: 10px; }
#settings-toast { color: var(--accent-deep); font-size: .85rem; font-weight: 600; }

/* ==========================================================================
   Scrollable data tables
   Each of these sits in a .table-shell that already scrolls. A min-width makes
   them scroll rather than crush their columns, which is what happened on a
   phone: the cells keep white-space:nowrap, so the text simply spilled out.
   ========================================================================== */

#report-table { min-width: 880px; }
#reporting-table { min-width: 560px; }
#logs-table { min-width: 700px; }
.table-shell { -webkit-overflow-scrolling: touch; }

/* ==========================================================================
   Responsive rules, narrowest last
   ========================================================================== */

/* "YourEasyShop" is one unbreakable word set in nowrap, so it cannot wrap its
   way out of a narrow panel - it has to be sized to fit one. At a fixed 3.15rem
   it only fits the brand panel on a wide desktop and was clipped by the panel
   edge below that. Above the 760px stacking point the panel tracks the viewport,
   so a fluid size holds it inside its column at every width while keeping the
   original size on a large screen. */
@media (min-width: 761px) {
  .brand-copy h1 { font-size: clamp(1.9rem, 3.6vw, 3.15rem); }
}

/* The two-column split in the overview and dispatch panels gets too tight well
   before the phone rules take over at 680px. */
@media (max-width: 860px) {
  .manifest-grid { grid-template-columns: minmax(0, 1fr); }
  .dropzone { min-height: 200px; }
}

@media (max-width: 680px) {
  /* The bar holds six nav items plus the brand and the account block, which is
     wider than a phone. body has overflow-x:hidden, so the overflow was clipped
     and User settings and Sign out could not be reached at all - the nav gets
     its own scroller instead. */
  .sidebar { gap: 10px; overflow-y: hidden; }
  .sidebar-nav {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sidebar-nav::-webkit-scrollbar { display: none; }
  .nav-item { flex: 0 0 auto; }
  .sidebar-brand { flex: 0 0 auto; }
  .sidebar-account { flex: 0 0 auto; }

  /* Three tab buttons do not fit on one phone row. */
  .tabs { flex-wrap: wrap; }
  .workspace-heading { flex-wrap: wrap; }

  /* Only .calculate-button and .secondary-button were told to stretch, so a
     stacked toolbar left its primary button at content width. */
  .toolbar-actions .save-data-button { flex: 1 1 160px; }

  .date-range { flex: 1 1 100%; }
  .date-input { flex: 1 1 0; height: 42px; }

  .settings-card { padding: 22px 18px; }
  .settings-avatar-row { gap: 16px; }
  .settings-actions .save-data-button { flex: 1 1 100%; }
  #settings-toast { flex: 1 1 100%; text-align: center; }
}

@media (max-width: 480px) {
  .dashboard:not(.is-manifest-view) .dashboard-main { padding: 24px 14px 32px; }
  .dashboard-header h1 { font-size: 1.85rem; }
  .dashboard.is-manifest-view .dashboard-header h1 { font-size: 1.55rem; }
  .workspace-heading { padding: 18px 16px; }
  .manifest-intro { padding: 24px 18px; }
  .manifest-intro h3 { font-size: 1.55rem; }
  .dropzone { margin: 14px; padding: 24px 12px; }
  .recent-heading { padding: 16px 16px; }
  .sheet-summary div { padding: 14px 16px; }
  .sheet-summary span { font-size: 1.15rem; }
  .sheet-status, .dashboard-status { padding-inline: 16px; }
  .workbench-toolbar { padding: 16px; }
  .table-save-bar { padding: 14px 16px; }
  /* Natural widths, so a wrapped third tab sits at the left of its row rather
     than stretching across the whole width. */
  .tab-btn { padding: 10px 12px; font-size: .78rem; }
  .settings-card { padding: 18px 14px; }
  .modal-backdrop { padding: 16px; }
  .brand-copy h1 { font-size: 2.1rem; }
}

/* Every table scrolls inside its shell on a phone, so the cells give back the
   side padding rather than the columns giving back their width. */
@media (max-width: 680px) {
  .table-shell > table > thead > tr > th,
  .table-shell > table > tbody > tr > td,
  .table-shell > table > tfoot > tr > td { padding: 12px 12px; }
  .dash-table > thead > tr > th, .dash-table > tbody > tr > td { padding: 13px 14px; }
}

/* A native date field will not shrink below roughly 130px whatever min-width it
   is given, so a start/end pair plus the separator needs about 300px. Below this
   the two of them widened the whole reporting toolbar past the screen. */
@media (max-width: 420px) {
  .date-range { flex-wrap: wrap; gap: 8px; }
  .date-range .date-input { flex: 1 1 100%; }
  .date-range-sep { flex: 1 1 100%; }
}

@media (max-width: 380px) {
  .dashboard-header h1 { font-size: 1.65rem; }
  .dashboard.is-manifest-view .dashboard-header h1 { font-size: 1.4rem; }
  .brand-copy h1 { font-size: 1.9rem; }
  .sidebar { padding-inline: 12px; }
  .nav-item { width: 44px; }
  .brand-panel { padding: 22px 20px; }
  .task-panel { padding: 30px 18px; }
}

/* A landscape phone is short, and in the manifest view the toolbar, summary,
   status line and save bar all compete with the table for 100dvh. */
@media (max-height: 600px) and (orientation: landscape) {
  .dashboard.is-manifest-view .workbench-toolbar { padding: 10px 16px; }
  .dashboard.is-manifest-view .sheet-summary div { padding: 10px 18px; }
  .dashboard.is-manifest-view .sheet-summary span { font-size: 1.05rem; }
  .dashboard.is-manifest-view .table-save-bar { padding: 10px 16px; }
  .dashboard.is-manifest-view .dashboard-main { gap: 8px; padding-block: 8px; }
}

@media (hover: none) and (pointer: coarse) {
  /* Mobile Safari zooms the whole page in when a focused field is under 16px,
     and never zooms back out. */
  .field input, .date-input, .settings-input, .sheet-cell-input { font-size: 16px; }
  /* Scoped to the sheet so it cannot override the taller settings and date
     fields, which are already comfortable touch targets. */
  #manifest-table .sheet-cell-input { height: 40px; }
  /* This label is revealed on hover, which a touch screen never reports, so the
     row's action read as permanently blank. */
  .file-row-action { opacity: 1; transform: none; }
}

/* The content column is capped at 1320px, which leaves a very wide desk mostly
   empty margin. */
@media (min-width: 1700px) {
  .dashboard:not(.is-manifest-view) .dashboard-main { max-width: 1560px; }
}



/* ==========================================================================
   QuickBooks export dialog
   The shared .modal-dialog is a centred confirmation; this one holds a form,
   so it reads left to right and its buttons sit on one row.
   ========================================================================== */

.qb-dialog { max-width: 420px; text-align: left; }
.qb-dialog h3 { margin: 0 0 6px; font-size: 1.15rem; }
.qb-summary { margin: 0 0 20px; color: var(--muted); font-size: .85rem; }
.qb-error { min-height: 0; margin: -8px 0 0; color: #a1223f; font-size: .8rem; }
.qb-error:not(:empty) { min-height: 20px; margin-bottom: 8px; }
.qb-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 12px; margin-top: 22px; }

@media (max-width: 480px) {
  .qb-actions { flex-direction: column-reverse; }
  .qb-actions .secondary-button, .qb-actions .save-data-button { width: 100%; }
}

/* ---------- Overview dashboard ----------
   The Overview used to be a second upload screen. It is now a read-only
   dashboard: the upload flow lives under Uploads, and this reports on what
   those uploads add up to, split between the two customers whose manifests
   the portal handles. Charts are hand-drawn SVG rather than a charting
   library, because the app ships no build step and vendors nothing it can
   avoid. */

.dash-header-actions { display: flex; align-items: center; gap: 12px; }
.dash-range { position: relative; display: inline-flex; }
/* Overview carries no Upload button any more — the upload form lives under
   Uploads — so the period picker takes over that button's accent slot and
   stays the one coloured control in the header. */
.dash-range select {
  appearance: none;
  min-height: 52px;
  padding: 0 42px 0 20px;
  font: inherit;
  font-size: .85rem;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
  border: 0;
  border-radius: 12px;
  box-shadow: 0 10px 22px rgba(185,48,89,.2);
  cursor: pointer;
  transition: transform .2s var(--ease), box-shadow .2s ease, background .2s ease;
}
.dash-range select:hover { transform: translateY(-2px); background: var(--accent-deep); box-shadow: 0 15px 28px rgba(185,48,89,.26); }
/* The dropdown list itself is painted by the OS, which would otherwise inherit
   white-on-white from the closed control. */
.dash-range select option { color: var(--ink); background: #fff; }
.dash-range::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 18px;
  width: 8px;
  height: 8px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.dash-range select:focus-visible { outline: 3px solid rgba(217,76,114,.25); outline-offset: 3px; }

/* ---- stat cards ---- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
  margin-bottom: 24px;
}
.stat-card {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 20px 22px;
  background: var(--paper);
  border-radius: 16px;
  box-shadow: 0 18px 50px rgba(43,36,30,.09), 0 4px 14px rgba(43,36,30,.05);
}
.stat-top { display: flex; align-items: center; gap: 12px; }
.stat-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  color: var(--tone, var(--accent));
  /* The flat tint is the fallback for browsers without color-mix(); the mixed
     one picks up whichever tone the card was given. */
  background: #f4f1ec;
  background: color-mix(in srgb, var(--tone, var(--accent)) 14%, #fff);
  border-radius: 11px;
}
.stat-icon svg { width: 19px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Wraps rather than truncates: "EasyShop Manifests" lost its last word to an
   ellipsis on a narrower screen, which is the one card whose label has to be
   read in full to tell it from the one beside it. */
.stat-label {
  min-width: 0;
  color: var(--muted);
  font-size: .82rem;
  font-weight: 600;
  line-height: 1.25;
}
.stat-bottom { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; }
.stat-value {
  margin: 0;
  overflow: hidden;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -.03em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat-delta { margin: 7px 0 0; color: var(--muted); font-size: .74rem; font-weight: 600; }
.stat-delta.is-up { color: #5f8d6c; }
.stat-ring { flex: 0 0 auto; display: grid; place-items: center; width: 46px; height: 46px; }
.stat-ring svg { width: 46px; height: 46px; }

/* ---- charts row ---- */
.dash-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 20px;
  margin-bottom: 24px;
}
.chart-card { display: flex; flex-direction: column; }
.chart-card .workspace-heading { align-items: flex-start; padding-bottom: 20px; }
.chart-note { color: var(--muted); font-size: .76rem; font-weight: 600; }
.chart-legend { display: flex; gap: 18px; margin: 10px 0 0; padding: 0; list-style: none; }
.chart-legend li { display: inline-flex; align-items: center; gap: 7px; color: var(--muted); font-size: .76rem; font-weight: 600; }
.swatch { width: 10px; height: 10px; border-radius: 3px; }
.swatch-shein { background: #e0a23c; }
.swatch-easyshop { background: #4c8fb0; }
.chart-body { flex: 1; padding: 22px 26px 24px; }
/* The chart keeps its aspect ratio as it widens, so on a single-column layout
   a full-width card would otherwise give it a half-metre of height. */
.chart-body svg { display: block; width: 100%; height: auto; max-height: 320px; overflow: visible; }
.chart-grid-line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; }
.chart-axis-label { fill: var(--muted); font-size: 10px; font-weight: 600; }
.chart-bar { transition: opacity .18s ease; }
.chart-bar:hover { opacity: .78; }

/* ---- donut ---- */
.donut-body { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 20px; padding: 24px 26px 26px; }
.donut-figure { position: relative; width: 170px; max-width: 100%; }
.donut-figure svg { display: block; width: 100%; height: auto; }
.donut-centre {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
}
.donut-centre strong { display: block; font-size: 1.5rem; letter-spacing: -.03em; }
.donut-centre span { display: block; margin-top: 3px; color: var(--muted); font-size: .7rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.donut-legend { width: 100%; margin: 0; padding: 0; list-style: none; }
.donut-legend li {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px solid #ebe7e1;
  font-size: .82rem;
}
.donut-legend li:first-child { border-top: 0; }
.donut-legend .donut-name { min-width: 0; overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.donut-legend .donut-share { color: var(--muted); font-weight: 700; }

/* ---- the two dashboard tables ----
   Recent manifests on the Overview, and the import history on the lookups
   screen. These read as a summary rather than a spreadsheet, so they keep the
   shared chrome but drop the vertical rules and sit on roomier rows.

   Both lay out to a fixed grid. Left to size themselves the file-name column
   swallowed whatever was left over - on a wide desk that was 300px of blank
   paper after a short name, with every other column crushed against the right
   edge - because the cells were all set to nowrap. Now the name is the only
   column that flexes, and it is the only one allowed to wrap. */
.dash-table { table-layout: fixed; }
.dash-table > thead > tr > th { padding: 14px 20px; background: var(--surface); color: var(--muted); font-size: .72rem; letter-spacing: .06em; }
.dash-table > tbody > tr > td { padding: 15px 20px; font-size: .86rem; white-space: nowrap; }
.dash-table .dash-sheet { font-weight: 700; white-space: normal; }

/* Overview - Sheet / Customer / Rows / Uploaded / Status / Actions */
#dash-recent-table th:nth-child(1) { width: auto; }
#dash-recent-table th:nth-child(2) { width: 130px; }
#dash-recent-table th:nth-child(3) { width: 90px; }
#dash-recent-table th:nth-child(4) { width: 130px; }
#dash-recent-table th:nth-child(5) { width: 140px; }
#dash-recent-table th:nth-child(6) { width: 110px; }
#dash-recent-table th:nth-child(3), #dash-recent-table td:nth-child(3) { text-align: right; }
#dash-recent-table th:nth-child(6), #dash-recent-table td:nth-child(6) { text-align: right; }

/* Lookups - File / Kind / What was read / Imported */
#lookups-log-table th:nth-child(1) { width: 26%; }
#lookups-log-table th:nth-child(2) { width: 120px; }
#lookups-log-table th:nth-child(3) { width: auto; }
#lookups-log-table th:nth-child(4) { width: 180px; }
/* The one long, sentence-like column in either table. */
#lookups-log-table td:nth-child(3) { white-space: normal; }

.dash-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px;
  font-size: .72rem;
  font-weight: 700;
  border-radius: 999px;
  /* The neutral case: a sheet whose customer could not be read. The modifiers
     below override it, so an unlabelled pill still looks deliberate. */
  color: #6f6a64;
  background: #ece8e2;
}
.dash-pill-shein { color: #8a5f12; background: #fbeed6; }
.dash-pill-easyshop { color: #27596f; background: #ddeef5; }
.dash-pill-done { color: #3f6b4c; background: #ddeee1; }
.dash-pill-pending { color: #8a5f12; background: #fbeed6; }
.dash-open {
  padding: 0;
  color: var(--accent-deep);
  font: inherit;
  font-size: .8rem;
  font-weight: 700;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.dash-open:hover { text-decoration: underline; }

/* ---- tab bars ---- */
.tabs { display: flex; gap: 12px; }
/* The Manifest Builder tabs sit between the page header and the first step
   card, where there is no workspace-heading to carry them. */
.mw-tabs { margin: -18px 0 22px; }
.recent-heading { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 28px 32px 24px; border-bottom: 1px solid var(--line); }
.recent-heading > div > span { display: block; margin-top: 6px; color: var(--muted); font-size: .8rem; }

/* Four cards need roughly 1320px of page before the money figures start
   wrapping against their rings; below that they read better two up. */
@media (max-width: 1320px) {
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-columns { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
  .dashboard-header { grid-template-columns: minmax(0, 1fr); }
  .dash-header-actions { flex-wrap: wrap; }
  .recent-heading { flex-wrap: wrap; padding: 22px 20px 18px; }
  .chart-body, .donut-body { padding: 18px 16px 20px; }
  .dash-table > thead > tr > th, .dash-table > tbody > tr > td { padding: 13px 16px; }
}

@media (max-width: 640px) {
  .stat-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .stat-value { font-size: 1.5rem; }
  .mw-tabs { margin-top: -8px; flex-wrap: wrap; }
  .dash-range select, .dash-header-actions .dashboard-upload { min-height: 46px; }
}

/* ---------- Uploads as a sidebar group ----------
   Uploads is a button now, not a link: it opens its flyout and nothing else.
   These rules only undo the button defaults, so it renders exactly like the
   anchors around it. */
button.nav-item {
  width: 100%;
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  text-align: left;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.nav-caret { width: 16px !important; margin-left: auto; opacity: .7; transition: transform .18s var(--ease); }
.nav-group-toggle[aria-expanded="true"] .nav-caret { transform: rotate(90deg); }

/* ---------- Manifest Builder lookups screen ---------- */
.lookup-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.lookup-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 26px;
  min-height: 230px;
  padding: 30px 32px;
  border-right: 1px solid var(--line);
}
.lookup-card:last-child { border-right: 0; background: #f8f6f2; }
.lookup-card h3 { margin: 0; font-size: 1.3rem; letter-spacing: -.02em; }
.lookup-card .mw-hint { max-width: 42ch; margin: 12px 0 0; color: var(--muted); font-size: .86rem; line-height: 1.6; }
.lookup-card-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; }

/* ---------- Dashboard: links out ---------- */
.dash-link {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-deep);
  font-size: .76rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.dash-link span { transition: transform .18s ease; }
.dash-link:hover span { transform: translateX(3px); }
.chart-heading-end { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }

/* The stat tiles are links; the arrow only shows that without shouting. */
a.stat-card { color: inherit; text-decoration: none; transition: transform .2s var(--ease), box-shadow .2s ease; }
a.stat-card:hover { transform: translateY(-3px); box-shadow: 0 22px 54px rgba(43,36,30,.12), 0 6px 16px rgba(43,36,30,.06); }
a.stat-card:focus-visible { outline: 3px solid rgba(217,76,114,.25); outline-offset: 3px; }
.stat-go { margin-left: auto; color: var(--accent-deep); font-weight: 700; opacity: 0; transform: translateX(-4px); transition: opacity .18s ease, transform .18s ease; }
a.stat-card:hover .stat-go, a.stat-card:focus-visible .stat-go { opacity: 1; transform: translateX(0); }

/* ---------- Dashboard: the two email consoles ---------- */
.dash-columns-even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.console-card { display: flex; flex-direction: column; color: inherit; text-decoration: none; transition: transform .2s var(--ease), box-shadow .2s ease; }
.console-card:hover { transform: translateY(-3px); box-shadow: 0 22px 54px rgba(43,36,30,.12), 0 6px 16px rgba(43,36,30,.06); }
.console-card:focus-visible { outline: 3px solid rgba(217,76,114,.25); outline-offset: 3px; }
.console-card .workspace-heading { align-items: center; padding: 22px 26px 20px; }
.console-title { display: flex; align-items: center; gap: 14px; min-width: 0; }
.console-title h2 { font-size: 1.12rem; }
.console-title .chart-note { display: block; margin-top: 4px; }
.console-body { flex: 1; display: flex; flex-direction: column; gap: 18px; padding: 22px 26px 24px; }
.console-figures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.console-figures .stat-value { font-size: 1.6rem; }
.console-breakdown { margin: 0; padding: 0; list-style: none; }
.console-breakdown li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-top: 1px solid #ebe7e1;
  font-size: .82rem;
}
.console-breakdown li:first-child { border-top: 0; }
.console-status { min-width: 0; overflow: hidden; color: var(--muted); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.console-count { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.console-latest { margin: auto 0 0; color: var(--muted); font-size: .76rem; }

@media (max-width: 1320px) {
  .dash-columns-even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  /* The sidebar collapses to icons, so the group caret goes with the labels. */
  .nav-caret { display: none !important; }
  .lookup-grid { grid-template-columns: minmax(0, 1fr); }
  .lookup-card { border-right: 0; border-bottom: 1px solid var(--line); padding: 24px 20px; }
  .lookup-card:last-child { border-bottom: 0; }
  .dash-columns-even { grid-template-columns: minmax(0, 1fr); }
  .console-card .workspace-heading, .console-body { padding-inline: 18px; }
}

@media (max-width: 680px) {
  /* The sidebar becomes a 68px bar across the top here. Its grid row was left
     to size itself, and because the grid is a min-height: 100dvh container the
     row stretched to swallow the leftover page height — on a phone that put a
     blank strip of up to 85px between the bar and the page heading. Sizing the
     two rows explicitly pins the bar to its own height and hands everything
     below it to the screen. The manifest workbench is left out: it runs its own
     full-height layout with the bar hidden. */
  .dashboard:not(.is-manifest-view) { grid-template-rows: auto minmax(0, 1fr); align-content: start; }
}
