/* Generated from src/shared/style.ts. */

:root {
  /* Warm, but off the khaki band entirely.
     Two earlier passes tried to fix this by desaturating and lightening while
     staying at hue 42, and both still read as dirt, because hue 40-60 at any
     saturation a person can see IS the olive/khaki range. The fix is the hue,
     not the saturation: everything neutral here now sits near hue 25, where a
     warm cast reads as plaster or linen rather than as something spoiled.
     Saturation is low enough that it stays a neutral and never competes with
     the seven highlight inks it has to sit behind. */
  --ground:   #e5dfda;   /* the desk */
  --panel:    #f7f4f2;   /* the tool's own surfaces sit on it */
  --surface:  #ffffff;   /* receipt paper, and nothing else */
  --ink:      #1e1a18;
  --muted:    #4b443f;
  --faint:    #5c534d;
  --rule:     #d5cec9;
  --rule-2:   #c4bab4;
  --accent:   #1c5a52;
  --accent-2: #164a43;

  --found:    #1c5a52;
  --missing:  #97301c;
  --unsure:   #765310;

  /* Paper on a desk, not a floating card. A single crisp line, no blur: the
     sheet reads as a sheet because the ground behind it is a real mid-tone,
     which is what was doing the work all along. */
  --lift:     0 0 0 1px var(--rule-2);

  /* The one number that makes a control thumb-sized. */
  --tap:      44px;

  --sans: "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --mono: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { box-sizing: border-box; }

html, body { background: var(--ground); color: var(--ink); }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

::selection { background: var(--accent); color: #fff; }

.shell { max-width: 48rem; margin: 0 auto; padding: 2.25rem 1.25rem 5rem; }

/* ------------------------------- typography ------------------------------- */

h1 {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.015em;
  margin: 0 0 0.4rem;
}
@media (min-width: 40rem) { h1 { font-size: 1.6rem; } }

.lede { color: var(--muted); margin: 0; max-width: 58ch; font-size: 0.95rem; }

/* Sans and a gentle tracking rather than letterspaced mono. The mono
   uppercase read as machine output; these are just section labels. */
.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 0.8rem;
}

a { color: var(--accent); text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 3px; transition: text-decoration-color .15s; }
a:hover { text-decoration-color: var(--accent); }

.section { border-top: 1px solid var(--rule); padding-top: 1.4rem; margin-top: 1.7rem; }
header.masthead { padding-bottom: 0.2rem; }

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

/* An invitation, not a boundary: a light dash with air around it. The radius
   is 8px, the ceiling for this family; 12px started to read as a bubble. */
.drop {
  display: block;
  border: 1px dashed var(--rule-2);
  border-radius: 8px;
  background: var(--panel);
  padding: 2rem 1.25rem;
  text-align: center;
  color: var(--muted);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.drop:hover, .drop.over { border-color: var(--accent); background: #fbf9f8; }
/* Reading has started. Dimmed rather than hidden, because the file name and
   the progress line under it are what someone is actually reading now. */
.drop.waiting { opacity: 0.55; cursor: progress; }
/* Once there is a receipt in hand this is a secondary action sitting under an
   answer, not the whole of the first screen. */
.drop.compact { padding: 1rem 1.25rem; }
.drop.compact strong { font-size: 0.95rem; }
.drop.compact small { font-size: 0.84rem; }
.drop strong { display: block; font-size: 1.05rem; font-weight: 600; color: var(--ink); margin-bottom: 0.3rem; }
.drop small { display: block; max-width: 34rem; margin: 0 auto; font-size: 0.88rem; line-height: 1.5; color: var(--muted); }
input[type=file] { display: none; }

/* Every button clears 44px. These were 34-41px, which is under a fingertip on
   the device this tool is mostly used on: a phone, holding a receipt. */
.action, .ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 600;
  border-radius: 6px;
  padding: 0 1.25rem;
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform .1s ease, background .15s, border-color .15s, color .15s;
}
/* The tactile press. Transform only, so it never triggers layout. */
.action:active:not(:disabled), .ghost:active, .reveal:active {
  transform: scale(0.98);
}
.action { background: var(--accent); color: #fff; border: 1px solid var(--accent); }
.action:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }
.action:disabled { background: transparent; color: var(--faint); border-color: var(--rule-2); cursor: not-allowed; }
.ghost { background: var(--panel); color: var(--ink); border: 1px solid var(--rule-2); }
.ghost:hover { border-color: var(--accent); color: var(--accent); }

.row { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; margin-top: 1rem; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --------------------------------- files --------------------------------- */

.files { list-style: none; margin: 0.9rem 0 0; padding: 0; }
.files li { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0; border-bottom: 1px solid var(--rule); font-size: 0.9rem; }
.files .name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.files .meta { font-family: var(--mono); font-size: 0.75rem; color: var(--faint); }
.files button {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--tap); min-height: var(--tap);
  border: 0; background: none; color: var(--faint); cursor: pointer;
  font-size: 1rem; line-height: 1; border-radius: 6px;
  -webkit-tap-highlight-color: transparent;
}
.files button:hover { color: var(--missing); }

/* -------------------------------- progress ------------------------------- */

.status { display: flex; align-items: center; gap: 0.55rem; font-size: 0.9rem; color: var(--muted); margin-top: 0.9rem; }
.spinner { width: 0.8rem; height: 0.8rem; flex: none; border-radius: 50%; border: 2px solid var(--rule-2); border-top-color: var(--accent); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 3s; } * { scroll-behavior: auto !important; } }

.note { font-size: 0.85rem; color: var(--faint); margin: 0.7rem 0 0; max-width: 62ch; }
.warning { border-left: 2px solid var(--missing); background: #f6e3dd; padding: 0.65rem 0.85rem; font-size: 0.9rem; color: var(--ink); margin-top: 0.9rem; border-radius: 0 4px 4px 0; }

/* Odyssey's conditional rules, when one of them applies to the pack on screen.
   Same left-rule language as .warning and .error, because they are the same
   kind of statement: something about this submission that is not a field on a
   page. The severity only moves the colour. A blocked rule and a needs-more
   rule share the missing red on purpose, because the parent's next move is the
   same either way, which is to stop and go and get a different document. */
.flags { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.5rem; }
.flag { border-left: 2px solid var(--missing); background: #f6e3dd; padding: 0.65rem 0.85rem; border-radius: 0 4px 4px 0; font-size: 0.9rem; color: var(--ink); }
.flag.check { border-left-color: var(--unsure); background: #f6eeda; }
.flag strong { display: block; font-weight: 600; margin-bottom: 0.15rem; }
.error { border-left: 2px solid var(--missing); background: #f6e3dd; color: var(--ink); padding: 0.65rem 0.85rem; font-size: 0.9rem; margin-top: 0.9rem; border-radius: 0 4px 4px 0; }

/* -------------------------------- verdict -------------------------------- */

/* The whole point of the page. A mark you can read from arm's length, a
   sentence saying what it means, and the one action that follows from it.
   This was a coloured left border and a 1.15rem heading, which is a caption,
   not an answer. */
.verdict {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 1.05rem;
  align-items: start;
  background: var(--panel);
  border: 1px solid var(--rule-2);
  border-left-width: 3px;
  border-radius: 8px;
  padding: 1.15rem 1.25rem;
  margin: 0 0 1.4rem;
}
.verdict .badge {
  width: 3.1rem; height: 3.1rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.65rem; font-weight: 600; line-height: 1; color: #fff;
}
.verdict h2 { font-size: 1.32rem; font-weight: 600; line-height: 1.25; margin: 0.3rem 0 0.35rem; letter-spacing: -0.015em; }
.verdict p { margin: 0; color: var(--muted); font-size: 0.92rem; max-width: 58ch; }
.verdict .row { margin-top: 0.95rem; }
.verdict.ok { border-left-color: var(--found); }
.verdict.ok .badge { background: var(--found); }
.verdict.ok h2 { color: var(--found); }
.verdict.warn { border-left-color: var(--unsure); }
.verdict.warn .badge { background: var(--unsure); }
.verdict.warn h2 { color: var(--unsure); }
.verdict.bad { border-left-color: var(--missing); }
.verdict.bad .badge { background: var(--missing); }
.verdict.bad h2 { color: var(--missing); }

/* One column under a narrow phone, where a 3.1rem badge beside a heading
   leaves the heading four words wide. */
@media (max-width: 30rem) {
  .verdict { grid-template-columns: 1fr; gap: 0.7rem 0; }
  .verdict .badge { width: 2.6rem; height: 2.6rem; font-size: 1.35rem; }
  .verdict h2 { margin-top: 0; }
}

/* ------------------------------- checklist ------------------------------- */

.checks {
  list-style: none; margin: 0; padding: 0 0.9rem;
  background: var(--panel); border: 1px solid var(--rule-2); border-radius: 6px;
}
.check { border-bottom: 1px solid var(--rule); }
.check:last-child { border-bottom: 0; }

/* The whole row is the "show me". It was a small link beside three other
   controls, it was the only one anybody used, and it is now the only thing a
   row does until the tools are open. */
.rowmain {
  display: grid;
  grid-template-columns: 1.4rem 1fr auto 3px;
  gap: 0 0.75rem;
  align-items: start;
  width: 100%;
  min-height: var(--tap);
  padding: 0.72rem 0;
  border: 0; background: none; color: inherit;
  font-family: var(--sans); text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  border-radius: 4px;
}
.rowmain:disabled { cursor: default; }
.rowmain:not(:disabled):hover .label { color: var(--accent); }

/* A tick, a cross, a question mark or a dash, in the state's own colour. The
   colour is never the only signal: the mark differs too, which is what makes
   this readable to someone who cannot tell the green from the red. */
.mark { font-size: 1.1rem; font-weight: 600; line-height: 1.25; text-align: center; }
.mark.found { color: var(--found); }
.mark.missing { color: var(--missing); }
.mark.unsure { color: var(--unsure); }
.mark.not_applicable { color: var(--faint); }

.rowmain .body { display: block; min-width: 0; }
.rowmain .label { display: block; font-weight: 600; font-size: 0.92rem; line-height: 1.35; transition: color .15s; }
/* Whatever came off the receipt is data, so it is set as data. */
.rowmain .value { display: block; font-family: var(--mono); color: var(--muted); font-size: 0.82rem; margin-top: 0.1rem; word-break: break-word; }
.rowmain .detail { display: block; color: var(--faint); font-size: 0.82rem; margin-top: 0.12rem; max-width: 54ch; }
.rowmain .why { display: block; color: var(--unsure); font-size: 0.82rem; margin-top: 0.12rem; max-width: 54ch; }

/* A word, in sentence case. FOUND in letterspaced mono was shouting. */
.state { font-size: 11.5px; font-weight: 600; white-space: nowrap; padding-top: 0.22rem; }
.state.found { color: var(--found); }
.state.missing { color: var(--missing); }
.state.unsure { color: var(--unsure); }
.state.not_applicable { color: var(--faint); }

/* The key to the colour of the box drawn on the page below. */
.swatch { align-self: stretch; border-radius: 1px; min-height: 1.4rem; }

.rowbtns { display: flex; gap: 0.35rem; padding: 0 0 0.7rem 2.15rem; flex-wrap: wrap; }
.mini {
  font-family: var(--sans); font-size: 11.5px;
  border: 1px solid var(--rule-2); background: var(--surface); color: var(--muted);
  border-radius: 5px; padding: 0.35rem 0.65rem; cursor: pointer; white-space: nowrap;
  transition: color .15s, border-color .15s;
}
.mini:hover { color: var(--ink); border-color: var(--faint); }
.mini.danger:hover { color: var(--missing); border-color: var(--missing); }
.mini.on { border-color: var(--accent); color: var(--accent); }

/* Opens everything this page used to lead with. */
.reveal {
  display: inline-flex; align-items: center; min-height: var(--tap);
  margin-top: 0.9rem; padding: 0;
  border: 0; background: none; cursor: pointer;
  font-family: var(--sans); font-size: 0.88rem; color: var(--accent);
  text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 4px;
  -webkit-tap-highlight-color: transparent;
  transition: transform .1s ease;
}
.reveal:hover { text-decoration-color: var(--accent); }

/* --------------------------------- pages --------------------------------- */

.pages { display: grid; gap: 1.4rem; }
.page-wrap { border: 1px solid var(--rule-2); border-radius: 4px; background: var(--surface); overflow: hidden; box-shadow: var(--lift); }
.page-head { font-size: 11.5px; color: var(--faint); padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--rule); background: #fbfaf9; }
.page-body { position: relative; line-height: 0; touch-action: none; }
.page-body.drawing { cursor: crosshair; }
.page-body img { width: 100%; height: auto; display: block; }
.hl { position: absolute; border-radius: 1px; pointer-events: none; mix-blend-mode: multiply; }
.hl.flash { animation: flash 1.1s ease-out 2; }
@keyframes flash { 0%,100% { opacity: 1; } 50% { opacity: .2; } }
.ghost-box { position: absolute; border: 1px dashed var(--ink); background: rgba(36,31,22,.08); pointer-events: none; }

.marking {
  position: sticky; top: 0; z-index: 5; margin-bottom: 0.9rem;
  background: var(--ink); color: #fff; border-radius: 4px;
  padding: 0.55rem 0.8rem; font-size: 0.88rem;
  display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap;
}
.marking i { width: 0.65rem; height: 0.65rem; border-radius: 1px; display: inline-block; flex: none; }
.marking button { margin-left: auto; background: rgba(255,255,255,.18); color: #fff; border: 0; border-radius: 3px; padding: 0.2rem 0.6rem; font-size: 0.8rem; cursor: pointer; font-family: var(--sans); }
.marking button:hover { background: rgba(255,255,255,.28); }

.legend { display: flex; flex-wrap: wrap; gap: 0.35rem 0.9rem; margin-bottom: 1rem; }
.legend span { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; color: var(--muted); }
.legend i { width: 0.6rem; height: 0.6rem; border-radius: 1px; display: inline-block; }

/* ---------------------------- combiner page grid -------------------------- */

.sheets { display: grid; grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); gap: 0.9rem; }
.sheet { border: 1px solid var(--rule-2); border-radius: 4px; background: var(--surface); overflow: hidden; box-shadow: var(--lift); }
.sheet-head { display: flex; justify-content: space-between; gap: 0.4rem; align-items: baseline; font-size: 11px; color: var(--faint); padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--rule); background: #fbfaf9; }
.sheet-head .n { color: var(--ink); font-weight: 500; }
.sheet-head .from { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0; }
.sheet-body { line-height: 0; }
.sheet-body img { width: 100%; height: auto; display: block; }
.sheet-foot { display: flex; gap: 0.2rem; padding: 0.35rem; border-top: 1px solid var(--rule); background: #fbfaf9; }
.sheet-foot button { flex: 1; border: 1px solid var(--rule-2); background: var(--panel); border-radius: 3px; font-size: 0.8rem; padding: 0.18rem 0; cursor: pointer; color: var(--faint); font-family: var(--sans); }
.sheet-foot button:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.sheet-foot button:disabled { opacity: .35; cursor: not-allowed; }

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

.rules { margin: 0; padding-left: 1.1rem; color: var(--muted); font-size: 0.9rem; }
.eyebrow.spaced { margin-top: 1.4rem; }
.rules li { margin-bottom: 0.4rem; }
.rules li:last-child { margin-bottom: 0; }
.rules strong { color: var(--ink); font-weight: 600; }

footer { border-top: 1px solid var(--rule); margin-top: 2.5rem; padding-top: 1rem; font-size: 0.82rem; color: var(--faint); line-height: 1.6; }

/* The footer nav is the only way from one receipt tool to the other, and its
   links were 18px tall. They are 44px rows now, laid out as a wrapping list so
   the row height cannot squeeze them back down. */
footer .links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.25rem; margin-top: 0.25rem; }
footer a { color: var(--muted); }
footer a:hover { color: var(--accent); }
footer .links a {
  display: inline-flex; align-items: center; min-height: var(--tap);
  padding-inline: 0.5rem; margin-inline: -0.5rem; border-radius: 6px;
}

/* ------------------------------ prose pages ------------------------------ */

.prose h1 { margin-bottom: 1.1rem; }
.prose h2 { font-size: 1rem; font-weight: 600; margin: 1.6rem 0 0.4rem; }
.prose p, .prose li { color: var(--muted); font-size: 0.95rem; }
.prose ul { padding-left: 1.1rem; }

:root {
  --accent:   #2a4a52;
  --accent-2: #4c676e;
  --found:    #2a4a52;
  --ground:   #f0f5f3;
  --panel:    #f8fcfc;
  --rule:     #dfe5e4;
  --rule-2:   #8b938f;
  --ink:      #1c1e1b;
  --muted:    #616460;
  --faint:    #616460;
  --missing:  #8a3a2a;
  --unsure:   #7d5a1e;
}
