/*
    The public grower surface.

    Mobile-first and deliberately plain: this renders as static SSR on a phone outdoors on rural
    4G (NFR-04), so there is no framework, no web font and nothing that blocks paint. A grower
    who cannot read the price does not submit, and they have no account to come back to.

    It is loaded INSTEAD OF farmos.css, not alongside it — App.razor picks per route — so this
    file carries its own small reset and base. It shares the token file, which is why the green
    here is the same green as "paid" on the driver's screen, and why dark mode works without a
    line of extra maintenance.
*/

/*
    No web font on this surface. farmos.css holds the only @font-face rules in the product and
    it is not loaded here, so these overrides are belt and braces — they keep a stray numeric
    class from reaching for a family that does not exist on this page.
*/
:root {
    --fo-font-ui: system-ui, -apple-system, "Segoe UI", sans-serif;
    --fo-font-num: ui-monospace, "Cascadia Mono", "Segoe UI Mono", monospace;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    /* 17px base: the default 16 is a touch small held at arm's length in daylight. */
    font-size: var(--fo-text-root);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/*
    Qualified with html, which is not cosmetic. Fluent's reboot also styles bare `body`, and
    although this file is linked after it, the reboot's margin and colour were the ones being
    painted - the page sat hard against the left edge of the screen with its text touching both
    sides on a phone, and only max-width (which the reboot does not set) survived from here.
    Two classes of selector on the same element is the one thing the cascade will not argue
    with, and the grower surface is not the place to be clever about it.
*/
html body {
    max-width: 38rem;
    margin-inline: auto;
    padding: var(--fo-s4);
    font-family: var(--fo-font-ui);
    font-size: var(--fo-text-base);
    line-height: var(--fo-leading-body);
    color: var(--fo-body);
    background: var(--fo-canvas);
}

h1,
h2 {
    margin: 0 0 var(--fo-s3);
    color: var(--fo-ink);
    line-height: var(--fo-leading-tight);
}

h1 {
    font-size: var(--fo-text-2xl);
    font-weight: var(--fo-weight-heavy);
    letter-spacing: -0.02em;
}

h2 {
    font-size: var(--fo-text-xl);
    font-weight: var(--fo-weight-bold);
}

p {
    margin: 0 0 var(--fo-s3);
}

a {
    color: var(--fo-settled);
    text-underline-offset: 0.15em;
}

code {
    font-family: var(--fo-font-num);
    word-break: break-all;
}

/*
    A link that is the page's one action - sign in, book the first pickup. A link rather than a
    button because it navigates and changes nothing, and a 44px target because it is tapped
    with a thumb in a yard (WCAG 2.5.8 wants 24; the rest of this surface uses 44).
*/
a.primary-action {
    display: inline-block;
    min-height: 44px;
    padding: 0.7rem 1.25rem;
    border-radius: var(--fo-radius-control);
    background: var(--fo-settled);
    color: var(--fo-on-accent);
    font-weight: var(--fo-weight-bold);
    text-decoration: none;
}

a.primary-action:hover,
a.primary-action:focus-visible {
    text-decoration: underline;
}

/* Visible focus is not decoration; it is how a keyboard user knows where they are. */
:focus-visible {
    outline: 3px solid var(--fo-focus);
    outline-offset: 2px;
}

/*
    Except on the heading Blazor focuses after a navigation. <ImportMap /> aside, every page
    on this surface loads with focus moved to its h1 so a screen reader announces where it
    landed - and because that element is given tabindex="-1", the rule above drew a blue box
    around the headline on first paint. Nobody tabs to a heading, so the ring tells a sighted
    visitor nothing and reads as a rendering fault on the first thing they ever see of this.
    The announcement still happens; only the box goes.
*/
[tabindex="-1"]:focus-visible {
    outline: none;
}

/* ---- Form ---- */

label {
    display: block;
    margin-block: var(--fo-s4);
    color: var(--fo-secondary);
    font-weight: 600;
}

input,
textarea,
select {
    display: block;
    width: 100%;
    min-height: var(--fo-target-min);
    margin-top: var(--fo-s1);
    padding: var(--fo-s2) var(--fo-s3);
    border: var(--fo-border) solid var(--fo-line-input);
    border-radius: var(--fo-radius-control);
    background: var(--fo-surface-1);
    color: var(--fo-body);
    /* 16px minimum stops iOS zooming the viewport on focus. */
    font: inherit;
    font-size: max(1rem, 16px);
    font-weight: var(--fo-weight-normal);
}

input[inputmode="numeric"],
input[type="number"],
input[type="date"] {
    font-family: var(--fo-font-num);
    font-variant-numeric: tabular-nums;
}

textarea {
    min-height: 5rem;
    resize: vertical;
}

::placeholder {
    color: var(--fo-muted);
    opacity: 1;
}

/* Earliest and latest sit side by side: they are one answer, asked twice. */
.window {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: var(--fo-s4);
}

.window label {
    margin-block: 0;
}

/* The commit action. One per page, and it is the only filled control on the surface. */
button {
    width: 100%;
    /* 56px: the smallest target a cold thumb reliably hits when it matters. */
    min-height: var(--fo-target-commit);
    margin-top: var(--fo-s4);
    padding: var(--fo-s3) var(--fo-s6);
    border: 0;
    border-radius: var(--fo-radius-control);
    background: var(--fo-settled);
    color: var(--fo-on-accent);
    font: inherit;
    font-size: var(--fo-text-lg);
    font-weight: var(--fo-weight-bold);
    cursor: pointer;
}

button:disabled {
    background: var(--fo-muted);
    cursor: not-allowed;
}

.hint {
    display: block;
    margin-top: var(--fo-s1);
    color: var(--fo-muted);
    font-size: var(--fo-text-sm);
    font-weight: var(--fo-weight-normal);
}

/* ---- The price, set like the ticket they will be handed ---- */

.pricing dl,
.submitted dl {
    margin: 0 0 var(--fo-s4);
}

.pricing dt {
    margin-top: var(--fo-s4);
    color: var(--fo-secondary);
    font-size: var(--fo-text-sm);
}

.pricing dd {
    margin: var(--fo-s1) 0 0;
}

/*
    The rate is the one number a grower is deciding on, so it is set as a figure — tabular,
    ink, and a size up — while the words around it stay ordinary text.
*/
.pricing dd strong,
.submitted strong {
    color: var(--fo-ink);
    font-family: var(--fo-font-num);
    font-size: var(--fo-text-xl);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

/* ---- States ---- */

.submitted {
    padding: var(--fo-s4);
    border: var(--fo-border) solid var(--fo-line);
    border-radius: var(--fo-radius-card);
    background: var(--fo-surface-1);
}

/*
    The floor promise, in the same green that means "settled" everywhere else in the product.
    It is the sentence the whole tier rule rests on, so it is a block and not a footnote.
*/
.floor {
    padding: var(--fo-s3);
    border-left: 4px solid var(--fo-settled);
    border-radius: 0 var(--fo-radius-control) var(--fo-radius-control) 0;
    background: var(--fo-settled-bg);
    color: var(--fo-settled);
    font-size: var(--fo-text-sm);
}

/* An upgrade is good news, so it reads as settled rather than as a change to worry about. */
.upgraded {
    display: block;
    margin-top: var(--fo-s1);
    color: var(--fo-settled);
    font-size: var(--fo-text-sm);
    font-weight: var(--fo-weight-medium);
}

.error {
    padding: var(--fo-s3);
    border-left: 4px solid var(--fo-held);
    border-radius: 0 var(--fo-radius-control) var(--fo-radius-control) 0;
    background: var(--fo-held-bg);
    color: var(--fo-held);
    font-size: var(--fo-text-sm);
}

.validation-message {
    display: block;
    margin-top: var(--fo-s1);
    color: var(--fo-held);
    font-size: var(--fo-text-sm);
    font-weight: var(--fo-weight-normal);
}

/* ---- Status list (the tracking page) ---- */

body > dl {
    display: grid;
    grid-template-columns: minmax(8rem, auto) 1fr;
    gap: var(--fo-s2) var(--fo-s4);
    margin: 0 0 var(--fo-s4);
    align-items: baseline;
}

body > dl dt {
    color: var(--fo-secondary);
    font-size: var(--fo-text-sm);
}

body > dl dd {
    margin: 0;
}

/* The honeypot. Off-screen rather than display:none, because some bots skip hidden fields. */
.hp {
    position: absolute;
    left: -9999px;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/*
    The two pages that can be reached by accident: a 404 and an unhandled error.

    Both now render on the public layout rather than the admin one. The 404 used to carry
    MainLayout, which meant an anonymous visitor who mistyped a URL was served the entire
    operator navigation - every admin destination by name and href.
*/

.not-found,
.error-page {
    display: flex;
    flex-direction: column;
    gap: var(--fo-s3);
    max-width: 38rem;
}

.not-found h1,
.error-page h1 {
    margin: 0;
}

/*
    Shared by the front door, the 404 and the error page. The public surface loads no web font
    and no farmos.css, so anything these pages use has to be defined here.
*/
.lede {
    margin: 0;
    color: var(--fo-secondary);
    font-size: var(--fo-text-lg);
}

.basis {
    margin: 0;
    color: var(--fo-muted);
    font-size: var(--fo-text-sm);
}

/*
    Text for assistive technology only. farmos.css carries the same utility for the admin
    surface; this surface does not load it.
*/
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/*
    The commit action is a fluent-button since the migration, so the rule above - written
    for a native <button> - stopped applying to it. It went back to inline-flex, and because
    Fluent wraps every control in a fluent-field that is inline-grid too, the controls on
    this form flow like words: the button came to rest on the same line as the notes field,
    printed across that field's label. On the one page where a grower has to find the button
    to be paid at all.

    Colour is left to Fluent - the bridge already points its brand token at --fo-settled, so
    the button is the same green as "paid" everywhere else. What is needed here is only that
    it take its own line, at the size a cold thumb can hit.
*/
form fluent-button {
    display: flex;
    width: 100%;
    min-height: var(--fo-target-commit);
    margin-top: var(--fo-s4);
}

/*
    Every control is wrapped in a fluent-field that defaults to inline-grid, so the inputs
    shrink-wrapped their content and sat at roughly half the width of the form - a name box
    narrower than the name going in it, on a phone held in one hand outdoors. Made
    block-level so each answer gets a line and the full measure, which is what the rest of
    this file was written for back when these were native inputs.

    The date pair is exempt: earliest and latest are one answer asked twice, and .window
    already puts them side by side.
*/
form fluent-field {
    display: grid;
}
