/* AIOS RECEIPTS — the receipt scanner and expense log (D194 / F160).
   ===========================================================================
   ITS OWN STYLESHEET, AND IT DOES NOT LOAD aios.css. That decision is a
   measurement rather than a preference, and it is the one F149 already recorded
   from the other side: `aios.css` is 105KB of a three-column dashboard, four
   layout modes, a weather scene and a note editor, none of which exists here.
   The AIOS landing page loads it because it re-uses thirteen of its classes on
   purpose; this app re-uses none of them.
   .
   WHAT IS SHARED IS THE PALETTE, COPIED BY VALUE FROM aios.css's :root. Copied
   rather than imported because an @import is a second render-blocking request
   for six declarations, and the two products are meant to LOOK like family
   rather than to track each other's every change -- if the brand colour ever
   moves, both move deliberately.
   .
   NO WEBFONT AND NO EXTERNAL REQUEST OF ANY KIND. Every visual is a gradient,
   a border or an inline SVG, so this directory's CSP needs nothing but 'self'
   -- the same argument the AIOS landing page made (F73), and here it also means
   the installed app renders identically with no network at all.
   .
   ONE BREAKPOINT, AT 780px, AND THAT IS THE WHOLE RESPONSIVE VOCABULARY. The
   dashboard needs four modes because it lays panels out in columns; this is one
   column of cards and a table, so a second threshold would be a number nobody
   measured. Where the table cannot fit it scrolls inside its own box, which is
   what keeps the PAGE from ever scrolling sideways.
   =========================================================================== */

:root {
    --rs-bg: #050505;
    --rs-surface: #0f0f0f;
    --rs-surface-2: #151515;
    --rs-border: rgba(46, 230, 214, 0.25);
    --rs-border-soft: rgba(255, 255, 255, 0.09);
    --rs-text: #ffffff;
    --rs-muted: #a8a8a8;
    --rs-accent: #2ee6d6;
    --rs-accent-deep: #1a9fa1;
    --rs-warn: #ffc65c;
    --rs-danger: #ff4b5c;
    --rs-ok: #4fdc8b;
    --rs-radius: 12px;
    --rs-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
    color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    /* System stack rather than a webfont: one fewer origin, one fewer
       render-blocking request, and nothing to fall back from. */
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 "Helvetica Neue", Arial, sans-serif;
    background: var(--rs-bg);
    color: var(--rs-text);
    line-height: 1.55;
    -webkit-text-size-adjust: 100%;
}

/* THE PAGE NEVER SCROLLS SIDEWAYS. Anything wider than the viewport scrolls
   inside its own box (see .rs-tablewrap), which is the rule this project has
   had to restate on five separate pages. */
body { overflow-x: hidden; }

a { color: var(--rs-accent); }
a:hover { color: #fff; }

h1, h2, h3 { line-height: 1.2; margin: 0 0 12px; }
h1 { font-size: clamp(1.9rem, 5vw, 3rem); letter-spacing: -0.02em; }
h2 { font-size: clamp(1.4rem, 3.4vw, 2rem); }
h3 { font-size: 1.05rem; }
p { margin: 0 0 14px; }

.rs-wrap { max-width: 1120px; margin: 0 auto; padding: 0 20px; }
.rs-narrow { max-width: 760px; }

/* --- the mark --------------------------------------------------------------
   Two lines, exactly as the app icon draws it (tools/make_app_icons.py
   --wordmark AIOS_RS), because the tile on somebody's home screen and the mark
   at the top of the page have to be recognisably the same object. The gradient
   is the same three stops. */
.rs-mark {
    display: inline-flex; flex-direction: column; align-items: center;
    justify-content: center;
    width: 44px; height: 44px; flex: 0 0 auto;
    border-radius: 11px;
    background: radial-gradient(circle at 30% 20%, #2ee6d6 0%, #1a9fa1 55%, #0b3b3c 100%);
    color: #fff; font-weight: 800; letter-spacing: 0.02em;
    line-height: 1; text-decoration: none;
}
.rs-mark span:first-child { font-size: 12px; }
.rs-mark span:last-child { font-size: 11px; }
/* A width on a flex item is a starting size, not a size — this stylesheet's
   own recurring lesson, five occurrences. */
.rs-mark, .rs-brand-text { flex: 0 0 auto; }

.rs-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.rs-brand-text { display: flex; flex-direction: column; }
.rs-brand-name { font-weight: 700; font-size: 15px; letter-spacing: 0.01em; }
.rs-brand-sub { font-size: 11px; color: var(--rs-muted); letter-spacing: 0.06em; text-transform: uppercase; }

/* --- top bar --------------------------------------------------------------- */
.rs-topbar {
    position: sticky; top: 0; z-index: 50;
    background: rgba(5, 5, 5, 0.96);
    border-bottom: 1px solid var(--rs-border-soft);
}
.rs-topbar-inner {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 10px 20px; max-width: 1120px; margin: 0 auto;
}
.rs-topnav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.rs-topnav a { font-size: 13px; text-decoration: none; padding: 8px 10px; border-radius: 8px; color: var(--rs-muted); }
.rs-topnav a:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }

/* A STICKY BAR MEANS AN ANCHOR CAN LAND UNDERNEATH IT (F107). The browser's
   own answer is read by a fragment navigation, by scrollIntoView and by a
   smooth scroll alike, so one declaration covers every route to an anchor. */
html { scroll-padding-top: 76px; }

/* --- buttons --------------------------------------------------------------- */
.rs-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    /* 44px of height is the platform tap floor both guidelines set, and F66
       removed a 32px target here once. Stated rather than left to padding. */
    min-height: 44px; padding: 10px 18px;
    border-radius: 10px; border: 1px solid var(--rs-border);
    background: transparent; color: var(--rs-accent);
    font: inherit; font-size: 14px; font-weight: 600; letter-spacing: 0.02em;
    text-decoration: none; cursor: pointer;
    transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.rs-btn:hover { background: rgba(46, 230, 214, 0.12); color: #fff; }
.rs-btn:focus-visible { outline: 2px solid var(--rs-accent); outline-offset: 2px; }
.rs-btn-primary {
    background: linear-gradient(135deg, var(--rs-accent), var(--rs-accent-deep));
    color: #041312; border-color: transparent;
}
.rs-btn-primary:hover { color: #000; filter: brightness(1.08); }
.rs-btn-sm { min-height: 34px; padding: 6px 11px; font-size: 12.5px; }
.rs-btn-danger { color: var(--rs-danger); border-color: rgba(255, 75, 92, 0.4); }
.rs-btn-danger:hover { background: rgba(255, 75, 92, 0.14); color: #fff; }
.rs-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.rs-btn[disabled]:hover { background: transparent; color: var(--rs-accent); }

/* --- cards / sections ------------------------------------------------------ */
.rs-section { padding: 62px 0; }
.rs-section-tight { padding: 34px 0; }
.rs-eyebrow {
    font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--rs-accent); margin-bottom: 10px;
}
.rs-lede { font-size: 1.08rem; color: var(--rs-muted); max-width: 62ch; }
.rs-card {
    background: linear-gradient(145deg, var(--rs-surface-2), var(--rs-surface));
    border: 1px solid var(--rs-border-soft);
    border-radius: var(--rs-radius);
    padding: 18px;
}
.rs-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.rs-card h3 { color: var(--rs-accent); }
.rs-card p:last-child { margin-bottom: 0; }
.rs-card-icon { display: block; margin-bottom: 10px; }

/* --- hero ------------------------------------------------------------------ */
.rs-hero { padding: 54px 0 34px; position: relative; overflow: hidden; }
.rs-hero-grid { display: grid; gap: 30px; grid-template-columns: 1fr; align-items: center; }
.rs-hero h1 { margin-bottom: 14px; }
.rs-hero-sub { font-size: 1.15rem; color: var(--rs-muted); max-width: 54ch; }
.rs-hero-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 22px; }
.rs-hero-note { font-size: 12.5px; color: var(--rs-muted); margin-top: 14px; }
.rs-hero-art { display: flex; justify-content: center; }
.rs-hero-art svg { width: 100%; max-width: 420px; height: auto; }

/* --- the three steps ------------------------------------------------------- */
.rs-steps { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); counter-reset: rs-step; }
.rs-step { position: relative; padding-top: 8px; }
.rs-step-n {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 50%;
    background: rgba(46, 230, 214, 0.14); border: 1px solid var(--rs-border);
    color: var(--rs-accent); font-weight: 700; font-size: 14px; margin-bottom: 10px;
}

/* --- tables ---------------------------------------------------------------- */
/* A WIDE TABLE SCROLLS INSIDE ITS OWN BOX. `overflow-x: auto` alone would
   compute overflow-y to auto as well and buy a phantom vertical scrollbar
   (F107's 15px), so both axes are stated. */
.rs-tablewrap { overflow-x: auto; overflow-y: hidden; border: 1px solid var(--rs-border-soft); border-radius: var(--rs-radius); }
table.rs-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rs-table th, .rs-table td { padding: 9px 11px; text-align: left; border-bottom: 1px solid var(--rs-border-soft); white-space: nowrap; }
.rs-table th { background: rgba(46, 230, 214, 0.08); color: var(--rs-accent); font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; position: sticky; top: 0; }
.rs-table tbody tr:hover { background: rgba(255, 255, 255, 0.035); }
.rs-table td.rs-num, .rs-table th.rs-num { text-align: right; font-variant-numeric: tabular-nums; }
.rs-table td.rs-wrap-cell { white-space: normal; min-width: 200px; }

/* --- forms ----------------------------------------------------------------- */
label { display: block; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--rs-muted); margin-bottom: 5px; }
input, select, textarea {
    width: 100%; padding: 10px 12px;
    background: #0a0a0a; color: var(--rs-text);
    border: 1px solid var(--rs-border-soft); border-radius: 9px;
    /* 16px IS A FLOOR ON EVERY TEXT INPUT AND IS NOT A STYLE CHOICE. Mobile
       Safari zooms the page in on a focused field below 16px and does not zoom
       back out, so a "tidier" 14px costs the user their whole viewport for the
       rest of the session. */
    font: inherit; font-size: 16px;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--rs-accent); box-shadow: 0 0 0 2px rgba(46, 230, 214, 0.18); }
textarea { min-height: 84px; resize: vertical; line-height: 1.5; }
.rs-field { margin-bottom: 14px; }
.rs-field-row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.rs-hint { font-size: 12px; color: var(--rs-muted); margin-top: 5px; text-transform: none; letter-spacing: 0; }

/* WHAT WAS READ AND WHAT WAS GUESSED, ON THE FIELD ITSELF. The parser reports
   provenance per field precisely so this can exist: a guessed total is the one
   number somebody has to look at, and a border is how it says so without a
   dialog. */
.rs-checkme input, .rs-checkme select, .rs-checkme textarea { border-color: var(--rs-warn); }
.rs-checkme label::after { content: " · check"; color: var(--rs-warn); }

/* --- status / messages ----------------------------------------------------- */
.rs-msg { min-height: 20px; font-size: 13px; margin: 8px 0; }
.rs-msg-ok { color: var(--rs-ok); }
.rs-msg-warn { color: var(--rs-warn); }
.rs-msg-err { color: var(--rs-danger); }
.rs-pill {
    display: inline-block; padding: 2px 9px; border-radius: 999px;
    font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
    border: 1px solid var(--rs-border-soft); color: var(--rs-muted);
}
.rs-pill-ok { color: var(--rs-ok); border-color: rgba(79, 220, 139, 0.4); }
.rs-pill-warn { color: var(--rs-warn); border-color: rgba(255, 198, 92, 0.4); }

/* --- the customisation ad --------------------------------------------------
   Owner: "Put a little ad saying we can customize to fit your business branding
   & add any custom tools you may need contact us as CaligoArts.com and direct
   them to the AI Integrations contact form."
   .
   IT IS A CARD IN THE FLOW, NEVER AN OVERLAY. An interstitial over an app
   somebody is working in is the thing everyone closes without reading, and it
   would sit on top of the receipt they are checking. In the flow it is read by
   the person who has just finished a task, which is when a "could this do more"
   question actually lands. */
.rs-promo {
    border: 1px solid var(--rs-border);
    background: linear-gradient(135deg, rgba(46, 230, 214, 0.10), rgba(26, 159, 161, 0.04));
    border-radius: var(--rs-radius); padding: 16px 18px;
}
.rs-promo h3 { color: var(--rs-accent); margin-bottom: 6px; }
.rs-promo p { color: var(--rs-muted); font-size: 13.5px; }
.rs-promo p:last-of-type { margin-bottom: 12px; }

/* --- footer ---------------------------------------------------------------- */
.rs-footer { border-top: 1px solid var(--rs-border-soft); padding: 28px 0 40px; color: var(--rs-muted); font-size: 13px; }
.rs-footer-links { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 10px; }

/* --- FAQ ------------------------------------------------------------------- */
details.rs-faq { border-bottom: 1px solid var(--rs-border-soft); padding: 12px 0; }
details.rs-faq summary { cursor: pointer; font-weight: 600; list-style: none; }
details.rs-faq summary::-webkit-details-marker { display: none; }
details.rs-faq summary::before { content: "+ "; color: var(--rs-accent); }
details.rs-faq[open] summary::before { content: "– "; }
details.rs-faq p { margin-top: 10px; color: var(--rs-muted); }

/* --- the login card -------------------------------------------------------- */
.rs-auth-body { min-height: 100dvh; display: flex; flex-direction: column; }
.rs-auth-main { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; padding: 28px 20px 60px; }
.rs-auth-card { width: 100%; max-width: 430px; }
.rs-auth-tabs { display: flex; gap: 6px; margin-bottom: 18px; }
.rs-auth-tabs .rs-btn { flex: 1 1 0; }
.rs-auth-tabs .rs-btn[aria-selected="true"] { background: rgba(46, 230, 214, 0.14); color: #fff; }

/* --- the app --------------------------------------------------------------- */
.rs-app-body { min-height: 100dvh; }
.rs-app-main { padding: 18px 0 90px; }
.rs-app-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.rs-app-head h2 { font-size: 1.5rem; margin: 0; }
.rs-totals { display: flex; gap: 10px; flex-wrap: wrap; margin-left: auto; }
.rs-total { text-align: right; }
.rs-total-v { font-size: 1.2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rs-total-k { font-size: 11px; color: var(--rs-muted); letter-spacing: 0.08em; text-transform: uppercase; }

.rs-toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.rs-toolbar .rs-grow { flex: 1 1 160px; min-width: 0; }
.rs-filters { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); margin-bottom: 14px; }

/* The scan control is a LABEL wrapping a hidden file input, not a button that
   clicks one: `capture="environment"` on a real file input opens the phone's
   own camera with no getUserMedia permission and no camera entry needed in
   this directory's Permissions-Policy. A styled button firing .click() on a
   hidden input is the same thing with one more thing to go wrong. */
.rs-scan-label { position: relative; overflow: hidden; }
.rs-scan-label input[type="file"] {
    position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%;
    cursor: pointer; font-size: 0;
}

.rs-review { display: grid; gap: 16px; grid-template-columns: 1fr; margin-bottom: 18px; }
.rs-review-img { text-align: center; }
.rs-review-img img {
    max-width: 100%; max-height: 46vh; border-radius: 10px;
    border: 1px solid var(--rs-border-soft);
}
.rs-ocr { max-height: 180px; overflow: auto; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11.5px; color: var(--rs-muted); white-space: pre-wrap; }

.rs-items-head { display: flex; align-items: center; gap: 8px; margin: 14px 0 8px; }
.rs-items-head h3 { margin: 0; }
.rs-item-row { display: grid; gap: 8px; grid-template-columns: 1fr 70px 100px 40px; align-items: center; margin-bottom: 8px; }
.rs-item-row input { font-size: 16px; }

.rs-empty { text-align: center; padding: 34px 18px; color: var(--rs-muted); }

/* --- SVG art helpers ------------------------------------------------------- */
.rs-svg-line { stroke: var(--rs-accent); stroke-width: 2; fill: none; }
.rs-svg-dim { stroke: rgba(255, 255, 255, 0.18); stroke-width: 2; fill: none; }
.rs-svg-fill { fill: rgba(46, 230, 214, 0.12); }

/* --- accessibility helpers -------------------------------------------------
   CLIP-RECT, NOT `display: none` (F130). The latter takes the label out of the
   accessibility tree entirely and leaves the field exactly as unlabelled as it
   was before somebody added it. */
.rs-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;
}
.rs-skip {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--rs-accent); color: #041312; padding: 10px 14px;
    border-radius: 0 0 8px 0; font-weight: 600;
}
.rs-skip:focus { left: 0; }

[hidden] { display: none !important; }

/* --- the free-trial banner (D195) ------------------------------------------
   IN THE FLOW AT THE TOP, never a fixed overlay. It has to be read once and
   then ignored; a bar pinned over the working area is the thing people close
   without reading, and this one has to still be there on the last day.
   .
   AMBER RATHER THAN RED, and only on the last two days does it change at all.
   Nothing is wrong -- a trial running is the normal state of a trial -- and a
   red strip on day one would train the reader to ignore the one on day
   thirteen. */
.rs-trial {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-bottom: 14px; padding: 10px 14px;
    border: 1px solid rgba(46, 230, 214, 0.3);
    background: rgba(46, 230, 214, 0.07);
    border-radius: var(--rs-radius);
    font-size: 13.5px;
}
.rs-trial .rs-btn { margin-left: auto; }
.rs-trial-soon {
    border-color: rgba(255, 198, 92, 0.45);
    background: rgba(255, 198, 92, 0.09);
    color: var(--rs-warn);
}

/* --- the ledger cell is a FINGER TARGET on a phone -------------------------
   MEASURED at 375x812: the table's own cell inputs came out 31-32px tall,
   which is under the ~44px both platform guidelines set -- on the one surface
   whose entire purpose is correcting a figure a camera got wrong. F66 removed
   a 32px target here once for exactly that reason.
   .
   THE HORIZONTAL TARGET WAS NEVER THE PROBLEM: the cells are 86-190px wide.
   So only the height is stated, and only where a finger is the input -- a
   mouse on a desktop is precise and a 44px row there would spend 13px per row
   of a ledger somebody scrolls. MEASURED cost at 375: five rows gain 65px in
   a page that already scrolls, which is the right way round.
   .
   THE OTHER SUB-44 CONTROLS ARE LEFT AS THEY ARE, DELIBERATELY: the top-bar
   links (36px) and the small pill buttons (34px) are secondary, and F114 has
   already settled that a secondary control may trade height for room when the
   primary one does not. The primary control here -- SCAN A RECEIPT -- measures
   147x44. */
@media (max-width: 779px) {
    .rs-table input, .rs-table select { min-height: 44px; }
}

/* --- wide screens ---------------------------------------------------------- */
@media (min-width: 780px) {
    .rs-hero-grid { grid-template-columns: 1.15fr 1fr; }
    .rs-review { grid-template-columns: 1fr 1fr; }
}

/* Motion is a courtesy and the user's setting is not negotiable. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { transition: none !important; animation: none !important; }
}
