/* ==========================================================================
   Untitled Needleworks — Employee verification
   Layered on site.css. Tokens, reset, nav, .shell, .skip and .vh all come from
   there; this file adds the two screens, the dark ground and nothing else.

   This is not a brand page. Someone enters an employee ID and reads back the
   record and its documents — often on a phone, often in poor light. Who they
   are and why they are looking varies: it may be staff checking a record, or
   the employee themselves fetching their own documents. The page does not
   assume, and the copy does not either.

   Every choice here serves reading the record quickly and correctly, and
   nothing else. No texture, no reveal, no entrance choreography that delays
   the one thing the reader came for.
   ========================================================================== */

/* ============================== GROUND ==============================
   Same three-state pattern policy.css uses, and for the same reason:

     1. bare :root                             — the light palette, always defined
     2. @media dark + :not([data-theme=light]) — the system preference
     3. :root[data-theme=dark]                 — the manual toggle, which wins

   Rule 3 must stay last or the toggle could not override the system in the
   light direction. Every value exists on the bare :root, so the page still
   paints if the media query never matches.

   Ratios are measured against the ground each token actually sits on, not
   assumed from the palette's own notes. */
:root {
    --emp-bg:       #F7F4ED;   /* cream-00                                   */
    --emp-raised:   #EFE9DC;   /* cream-10  — cards, fields                  */
    --emp-text:     #4A3728;   /* brown-70  — body               10.23:1     */
    --emp-head:     #241B12;   /* brown-90  — headings, values   15.41:1     */
    --emp-muted:    #6F5945;   /* brown-50  — labels              5.99:1     */
    --emp-accent:   #A8460F;   /* orange-70 — small text          5.39:1     */
    --emp-edge:     #8A7660;   /* boundaries                      3.95:1     */
    --emp-rule:     #C4B49E;   /* decorative hairlines only                  */
    --emp-focus:    #C2571C;   /* orange-60                       4.09:1     */

    /* The current-status chip. Solid fill, light text — the inversion is what
       survives greyscale, not the hue. */
    --emp-now-bg:   #A8460F;
    --emp-now-fg:   #F7F4ED;   /*                                 5.39:1     */

    --emp-navbg:    rgba(247, 244, 237, 0.92);
    color-scheme: light;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --emp-bg:      #0B0704;   /* stage-ground — the brand's own dark     */
        --emp-raised:  #241B12;   /* brown-90                                */
        --emp-text:    #E2D9C8;   /* cream-20                     14.33:1    */
        --emp-head:    #F7F4ED;   /* cream-00                     18.27:1    */
        --emp-muted:   #C4B49E;   /* brown-20                      9.91:1    */
        --emp-accent:  #E08A4B;   /* orange-40                     7.56:1    */
        --emp-edge:    #8A7660;   /* clears 3:1 on both grounds    4.63:1    */
        --emp-rule:    #4A3728;
        --emp-focus:   #C2571C;   /*                               4.47:1    */
        --emp-now-bg:  #E08A4B;
        --emp-now-fg:  #0B0704;   /*                               7.56:1    */
        --emp-navbg:   rgba(11, 7, 4, 0.92);
        color-scheme: dark;
    }
}

:root[data-theme="dark"] {
    --emp-bg:      #0B0704;
    --emp-raised:  #241B12;
    --emp-text:    #E2D9C8;
    --emp-head:    #F7F4ED;
    --emp-muted:   #C4B49E;
    --emp-accent:  #E08A4B;
    --emp-edge:    #8A7660;
    --emp-rule:    #4A3728;
    --emp-focus:   #C2571C;
    --emp-now-bg:  #E08A4B;
    --emp-now-fg:  #0B0704;
    --emp-navbg:   rgba(11, 7, 4, 0.92);
    color-scheme: dark;
}

html { background: var(--emp-bg); }

/* site.css leaves body transparent for the homepage cloth canvas. There is no
   cloth here, so the ground gets painted. */
.emp-body {
    background: var(--emp-bg);
    color: var(--emp-text);
}

:focus-visible { outline: 2px solid var(--emp-focus); outline-offset: 3px; }

/* ============================== NAV ==============================
   Same bar as the policy pages: carries its ground from the first pixel (there
   is no hero to sit over and reveal.js is not loaded here) and follows the dark
   ground. Below 640px site.css hides the bar entirely because the footer is the
   navigation there — that cannot happen here, because the theme control lives
   in the bar and a reader on a phone in bad light is exactly who needs it. */
.emp-body .nav {
    background-color: var(--emp-navbg);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--emp-rule);
}
/* One correction to the shared wordmark, scoped so the rest of the site keeps
   the bar it has: site.css paints it --brown-90 on .page--light pages, at a
   specificity a plain .emp-body descendant selector loses to. On the dark
   ground that is near-black on near-black. The second selector matches
   site.css's own shape, exactly as policy.css does, so the later stylesheet
   wins the tie rather than needing !important.

   The 44x44 floor that used to sit here too is now unconditional in site.css,
   on .nav__mark itself — it was never specific to these two pages. */
.emp-body .nav__mark,
.page--light .emp-nav:not(.is-stuck) .nav__mark {
    color: var(--emp-head);
}

@media (max-width: 639.98px) {
    .emp-body .nav { display: block; }
    .emp-body .nav__inner { padding-block: var(--s3); gap: var(--s3); }
}

.emp-tools { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); }

.emp-tool {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    min-height: 44px;              /* touch target, every width */
    padding: 0 var(--s4);
    font-family: var(--font-text);
    font-size: 0.75rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--emp-text);
    background: var(--emp-raised);
    border: 1px solid var(--emp-edge);
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
}
.emp-tool svg { width: 15px; height: 15px; fill: currentColor; display: block; }

/* With scripting off the toggle would do nothing, so it is not offered.
   prefers-color-scheme still works on its own — it is plain CSS. */
.no-js .emp-tool--theme { display: none; }

/* ============================== SHELL ==============================
   Narrower than the site shell. A lookup form and a record are both single
   columns of facts; the site's 1280px is a composition width and would strand
   the values miles from their labels on a laptop. */
/* site.css fixes the nav to the top of the viewport, so the first thing in
   <main> has to clear it or the wordmark sits on top of the h1. The bar is
   its 44px controls plus its own padding: 69px below 640 where the padding
   tightens, 77px above it. 96px clears both with room, at every width. */
.emp {
    padding-block: 96px var(--s8);
}
.emp__shell {
    width: 100%;
    max-width: 40rem;
    margin: 0 auto;
    padding-inline: var(--gutter);
}
.emp__shell--wide { max-width: 52rem; }

.emp__title {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 5vw, 2rem);
    line-height: 1.15;
    letter-spacing: 0.01em;
    color: var(--emp-head);
}
.emp__lead {
    margin-top: var(--s3);
    color: var(--emp-muted);
    font-size: 0.9375rem;
    line-height: 1.6;
}

/* ============================== LOOKUP FORM ==============================
   A real <form>. Enter submits because the browser makes it submit, not
   because a key handler was remembered. */
.emp-form { margin-top: var(--s6); }

.emp-form__label {
    display: block;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--emp-muted);
    margin-bottom: var(--s2);
}

.emp-form__row { display: flex; flex-wrap: wrap; gap: var(--s3); }

.emp-form__input {
    flex: 1 1 12rem;
    /* 12rem, not a px min-width: the flex-basis may shrink below it, so the
       field can never be the thing that widens the page. */
    min-width: 0;
    min-height: 52px;
    padding: 0 var(--s4);
    /* 1.0625rem — at or above 16px, or iOS Safari zooms the page on focus and
       the reader lands on a viewport they did not ask for. */
    font-family: var(--font-text);
    font-size: 1.0625rem;
    letter-spacing: 0.04em;
    color: var(--emp-head);
    background: var(--emp-raised);
    border: 1px solid var(--emp-edge);
    border-radius: 2px;
}
.emp-form__input::placeholder { color: var(--emp-muted); opacity: 1; }

.emp-form__submit {
    flex: 1 1 8rem;
    min-width: 0;
    min-height: 52px;
    padding: 0 var(--s5);
    font-family: var(--font-text);
    font-size: 0.9375rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--emp-now-fg);
    background: var(--emp-now-bg);
    border: 1px solid var(--emp-now-bg);
    border-radius: 2px;
    cursor: pointer;
}

/* The form's own error, for an empty submit. Replaces the alert() the page
   used to throw, which blocked the whole tab and said nothing a sighted
   reader could not already see. */
.emp-form__error {
    margin-top: var(--s3);
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--emp-accent);
}
.emp-form__error:empty { display: none; }

/* What this page is, and what it will never ask for. An unbranded box asking
   for an identifier is the shape of a phishing page; saying so plainly is the
   cheapest defence available. */
.emp__note {
    margin-top: var(--s6);
    padding: var(--s4);
    border-left: 3px solid var(--emp-edge);
    background: var(--emp-raised);
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--emp-text);
}

/* ============================== RECORD ============================== */
.rec {
    margin-top: var(--s6);
    background: var(--emp-raised);
    border: 1px solid var(--emp-rule);
    border-radius: 3px;
    padding: var(--s5);
}
@media (min-width: 620px) { .rec { padding: var(--s6); } }

.rec__head {
    display: flex;
    align-items: flex-start;
    gap: var(--s4);
}

/* --- photo -------------------------------------------------------------
   A fixed square at every width, with a caption line under it. The square
   never changes size between states, so nothing around the photo moves when
   one resolves into another.

   The default image is the generic grey silhouette in employees/photo.webp.
   It stands in for two different facts, and on its own it cannot tell them
   apart, so it never appears without the caption saying which one it is:

     no photo on record   normal for many records
     photo did not load   the record HAS a photo and this is an outage

   Those are different facts and the caption is what carries the difference.
   The frame border is a second channel: dashed for absent, a heavier accent
   border for a fault. */
.rec__photo {
    --photo: 88px;
    flex: 0 0 auto;
    width: var(--photo);
}
@media (min-width: 400px) { .rec__photo { --photo: 112px; } }
@media (min-width: 720px) { .rec__photo { --photo: 148px; } }

.rec__photo-frame {
    width: var(--photo);
    height: var(--photo);
    border: 1px solid var(--emp-edge);
    border-radius: 2px;
    overflow: hidden;
    background: var(--emp-bg);
}
.rec__photo-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rec__photo-note {
    margin-top: var(--s2);
    font-size: 0.6875rem;
    line-height: 1.3;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-align: center;
    color: var(--emp-muted);
    overflow-wrap: anywhere;
}
@media (min-width: 400px) { .rec__photo-note { font-size: 0.75rem; } }

/* Absent is the quiet state — it is expected, and it is not a fault. */
.rec__photo--none .rec__photo-frame { border-style: dashed; }

/* Pending is not an outcome. It shows no default image at all, so it cannot
   be mistaken for "no photo on record" while it is still deciding. */
.rec__photo--pending .rec__photo-frame { border-style: dotted; }

/* A photo that exists and did not arrive is a fault, and reads as one. */
.rec__photo--failed .rec__photo-frame {
    border: 2px solid var(--emp-accent);
}
.rec__photo--failed .rec__photo-note { color: var(--emp-accent); }

.rec__photo-mark { font-style: normal; }

/* --- identity ---------------------------------------------------------- */
.rec__ident { min-width: 0; }   /* lets long names wrap instead of pushing */

.rec__id {
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--emp-muted);
    overflow-wrap: anywhere;
}
.rec__name {
    margin-top: var(--s1);
    font-family: var(--font-display);
    font-size: clamp(1.25rem, 5.5vw, 1.875rem);
    line-height: 1.15;
    color: var(--emp-head);
    overflow-wrap: anywhere;
}

/* --- status -----------------------------------------------------------
   Sits directly under the name, inside the same glance. The literal sheet
   value is always what is printed — no substituted wording, no advice about
   what to do with it.

   Current and not-current differ by FILL, not hue: the current chip is a solid
   block with inverted text, every other value is an outline with body text.
   In greyscale that is still a dark block against a light one. The leading
   mark is a second, non-colour channel. */
.rec__status {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    margin-top: var(--s3);
    padding: var(--s2) var(--s4);
    border-radius: 2px;
    font-size: 0.875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 700;
    /* Not a tap target — it is a fact, not a control — but it must not be so
       small it is missed. */
    min-height: 34px;
    color: var(--emp-text);
    background: transparent;
    border: 1px solid var(--emp-edge);
    overflow-wrap: anywhere;
}
.rec__status::before {
    content: "";
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 2px solid currentColor;
    background: transparent;
}
.rec__status--current {
    color: var(--emp-now-fg);
    background: var(--emp-now-bg);
    border-color: var(--emp-now-bg);
    font-size: 0.9375rem;
}
.rec__status--current::before { background: currentColor; }

/* --- facts -------------------------------------------------------------
   A description list, because that is what it is: terms and their values.
   One column on a phone so a long value never has to share a line. */
.rec__facts {
    margin-top: var(--s5);
    padding-top: var(--s5);
    border-top: 1px solid var(--emp-rule);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s4);
}
@media (min-width: 620px) { .rec__facts { grid-template-columns: 1fr 1fr; gap: var(--s5); } }

.rec__term {
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--emp-muted);
}
.rec__val {
    margin-top: var(--s1);
    font-size: 1.0625rem;
    color: var(--emp-head);
    overflow-wrap: anywhere;
}

/* --- files -------------------------------------------------------------
   One control per file. There used to be two — View and Download — pointing at
   the same Drive URL, where Download additionally navigated the current tab
   away from the record the reader was mid-way through checking. */
.rec__files {
    margin-top: var(--s5);
    padding-top: var(--s5);
    border-top: 1px solid var(--emp-rule);
}
.rec__files-h {
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--emp-muted);
    margin-bottom: var(--s3);
}
.rec__file {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) 0;
    border-bottom: 1px solid var(--emp-rule);
}
.rec__file:last-child { border-bottom: 0; }

.rec__file-name {
    flex: 1 1 10rem;
    min-width: 0;
    font-size: 1rem;
    color: var(--emp-head);
    overflow-wrap: anywhere;
}

.rec__open {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s2);
    min-height: 44px;
    min-width: 44px;
    padding: 0 var(--s5);
    font-size: 0.875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 700;
    text-decoration: none;
    color: var(--emp-accent);
    background: var(--emp-bg);
    border: 1px solid var(--emp-edge);
    border-radius: 2px;
}
.rec__open svg { width: 14px; height: 14px; fill: currentColor; display: block; }

/* A file row the endpoint flagged. Shown in place of the control rather than
   dropped, so a broken row in the sheet is visible to whoever can fix it. */
.rec__file-problem {
    flex: 0 0 auto;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--emp-accent);
    padding: var(--s2) 0;
}

/* ============================== WHOLE-CARD STATES ==============================
   Not found, not configured, unreachable. These replace the record rather than
   dropping a line into it: with no employee there is nothing for a name, a
   photo or a file list to be about. */
.state {
    margin-top: var(--s6);
    background: var(--emp-raised);
    border: 1px solid var(--emp-rule);
    border-left: 3px solid var(--emp-accent);
    border-radius: 3px;
    padding: var(--s5);
}
.state__h {
    font-family: var(--font-display);
    font-size: clamp(1.125rem, 4.5vw, 1.5rem);
    line-height: 1.2;
    color: var(--emp-head);
}
.state__p { margin-top: var(--s2); color: var(--emp-text); font-size: 0.9375rem; }

/* ============================== BACK LINK ============================== */
.emp-back {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    min-height: 44px;
    padding: 0 var(--s4) 0 0;
    margin-top: var(--s6);
    font-size: 0.875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--emp-accent);
    text-decoration: none;
}

/* ============================== FOOTER ==============================
   The site footer is four columns of navigation. None of that belongs on an
   internal tool, so this is the same idea at the scale the page warrants:
   who this is, what the page is for, and the way back to the public site.
   Ground and type follow the site's footer convention — dark in both themes. */
.emp-foot {
    margin-top: var(--s8);
    background-color: var(--brown-90);
    color: var(--cream-20);
    padding-block: var(--s6);
    border-top: 1px solid var(--emp-rule);
}
.emp-foot__inner {
    width: 100%;
    max-width: 52rem;
    margin: 0 auto;
    padding-inline: var(--gutter);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3) var(--s5);
}
.emp-foot__brand { display: flex; align-items: center; gap: var(--s3); flex: 1 1 16rem; min-width: 0; }
.emp-foot__logo { width: 40px; height: 40px; flex: 0 0 auto; }
.emp-foot__mark {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cream-00);
}
.emp-foot__line { font-size: 0.8125rem; color: var(--brown-20); line-height: 1.5; }

/* The site footer closes with a rule and a copyright line; this is that, at
   the scale an internal tool warrants. Same wording and same token as
   .foot__credit, which is identical on all 24 pages that carry it. */
.emp-foot__bottom {
    margin-top: var(--s5);
    padding-top: var(--s4);
    border-top: 1px solid var(--brown-70);
}
.emp-foot__credit { font-size: 0.8125rem; color: var(--brown-20); }
.emp-foot__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--s4);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cream-20);
    border: 1px solid var(--brown-70);
    border-radius: 2px;
    text-decoration: none;
    flex: 0 0 auto;
}

/* ============================== MOTION ==============================
   One fade, short, and only on the record — it is the only thing that arrives
   after the page has already painted, and without it the card appears with no
   indication anything happened. Nothing else on either page animates. */
@keyframes emp-in { from { opacity: 0; } to { opacity: 1; } }
.rec, .state { animation: emp-in 160ms ease-out both; }

@media (prefers-reduced-motion: reduce) {
    .rec, .state { animation: none; }
    html { scroll-behavior: auto; }
}
