/* -------------------------------------------------------------------------
   The writer verification page.

   Sits inside the ordinary article wrapper, so it inherits the paper's own
   frame -- header, sidebar, ticker -- and only styles its own document. Same
   per-section-stylesheet convention as assignment.css / wiki.css / polls.css.

   SPECIFICITY WARNING, learned twice on the assignment notice: this document
   renders inside `.article-container`, and custom.css carries rules like
   `.article-container h3 { font-size: 24px }` at specificity (0,1,1) -- a
   class AND an element. A bare class here is (0,1,0) and loses silently, and
   the result usually looks *almost* right, which is why it survives review.
   Everything that styles a plain element is therefore scoped `.writer-doc x`.
   ------------------------------------------------------------------------- */

:root {
    --writer-ink: #16181a;
    --writer-muted: #5f646b;
    --writer-rule: #c9c8c2;
    --writer-rule-soft: #e4e3dd;
    --writer-paper: #fffef8;
    --writer-blue: #164f8b;
    --writer-green: #2f6b4d;
    --writer-red: #a62d2d;
    --writer-amber: #8a5d00;
    --writer-ui: Arial, Helvetica, sans-serif;
    --writer-serif: Georgia, 'Times New Roman', serif;
}

/* custom.css sets `body { overflow: hidden }` and every other page releases it
   from its preloader's onload handler. This layout has no preloader, so
   without this the document cannot be scrolled. Copied from wiki.css and
   assignment.css for exactly that reason. */
.osc-writer-body {
    margin: 0;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    background: #FFFFF7;
}
.osc-writer-body .header { top: 0; }

.writer-doc {
    font-family: var(--writer-serif);
    color: var(--writer-ink);
    line-height: 1.6;
    max-width: 46rem;
}
.writer-doc p { margin: 0 0 1.05em; font-size: 1.0625rem; }
.writer-doc a { color: var(--writer-blue); }

/* -- the verification bar ------------------------------------------------- */

/* The reason the page exists, and therefore the first thing on it. Somebody
   standing at a door with a telephone in their hand needs the answer above the
   fold, not after a biography. */
.writer-doc .writer-verify {
    position: relative;
    overflow: hidden;                 /* keeps the shimmer inside the bar */
    padding: 18px 22px;
    margin: 0 0 26px;
    border: 1px solid var(--writer-rule);
    border-left: 6px solid var(--writer-green);
    background: linear-gradient(180deg, #f6faf7 0%, #fbfdfb 100%);
}
.writer-doc .writer-verify.is-former {
    border-left-color: var(--writer-muted);
    background: linear-gradient(180deg, #f5f4f0 0%, #faf9f6 100%);
}
.writer-doc .writer-verify.is-suspended {
    border-left-color: var(--writer-red);
    background: linear-gradient(180deg, #fbf3f3 0%, #fdf8f8 100%);
}

/* The shimmer.

   A slow light sweep across the bar, roughly every seven seconds. It exists
   because a verification claim that sits there perfectly static is exactly
   what a screenshot of a verification claim looks like -- a little motion says
   the page is being served right now, live, by something.

   It is DECORATION AND NOTHING ELSE. No script reads it, nothing waits on it,
   and if it never runs the page is unchanged. That is deliberate: this
   codebase has twice shipped a bug where a state change hung off an animation
   that never fired in a backgrounded tab.

   transform only, so it composites on the GPU and never triggers layout. */
.writer-verify-shimmer {
    position: absolute;
    top: 0;
    left: 0;
    width: 45%;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(
        100deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.72) 50%,
        rgba(255, 255, 255, 0) 100%
    );
    transform: translateX(-140%);
    animation: writer-shimmer 7s cubic-bezier(0.35, 0, 0.2, 1) 1.2s infinite;
}
@keyframes writer-shimmer {
    /* Sweeps once, then rests. A continuous sweep reads as a loading bar --
       something waiting on data -- which is the wrong signal entirely. */
    0%   { transform: translateX(-140%); }
    28%  { transform: translateX(320%); }
    100% { transform: translateX(320%); }
}

/* A thin live rule along the top, the same idea held still. */
.writer-doc .writer-verify::after {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 2px;
    background: linear-gradient(90deg,
        var(--writer-green) 0%, #7ec99f 45%, var(--writer-green) 100%);
    background-size: 200% 100%;
    animation: writer-rule-drift 9s linear infinite;
}
.writer-doc .writer-verify.is-former::after {
    background: var(--writer-muted); animation: none;
}
.writer-doc .writer-verify.is-suspended::after {
    background: linear-gradient(90deg, var(--writer-red) 0%, #d98c8c 45%, var(--writer-red) 100%);
    background-size: 200% 100%;
}
@keyframes writer-rule-drift {
    from { background-position: 0% 0; }
    to   { background-position: 200% 0; }
}

/* Nobody asked for this movement, so anybody who has asked for less gets none.
   Both the sweep and the drifting rule stop; the bar keeps its colour and
   every word stays exactly where it was. */
@media (prefers-reduced-motion: reduce) {
    .writer-verify-shimmer { animation: none; opacity: 0; }
    .writer-doc .writer-verify::after { animation: none; }
}

.writer-doc .writer-verify-paper {
    margin: 0 0 2px;
    font-family: var(--writer-ui);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--writer-muted);
}
.writer-doc .writer-verify-claim {
    margin: 0 0 4px;
    font-family: var(--writer-ui);
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--writer-green);
}
.writer-doc .writer-verify.is-former .writer-verify-claim { color: #3f4550; }
.writer-doc .writer-verify.is-suspended .writer-verify-claim { color: var(--writer-red); }

.writer-doc .writer-verify-since,
.writer-doc .writer-verify-note {
    margin: 0 0 4px;
    font-size: .9375rem;
    line-height: 1.5;
}
.writer-doc .writer-verify-note { font-style: italic; }
.writer-doc .writer-verify-checked {
    margin: 8px 0 0;
    font-family: var(--writer-ui);
    font-size: .78rem;
    color: var(--writer-muted);
}

/* -- who they are --------------------------------------------------------- */

.writer-doc .writer-head {
    display: flex;
    gap: 20px;
    align-items: flex-start;
    padding-bottom: 20px;
    margin-bottom: 6px;
    border-bottom: 2px solid var(--writer-ink);
}
.writer-shot {
    flex: 0 0 150px;
    width: 150px; height: 150px;
    object-fit: cover;
    border: 1px solid var(--writer-rule);
    border-radius: 2px;
    background: #f2f1ec;
}
/* Initials, not a stock silhouette. A generic grey person on a page whose only
   job is identification is worse than no picture at all. */
.writer-shot--none {
    display: flex; align-items: center; justify-content: center;
    font-family: var(--writer-ui);
    font-size: 3rem; font-weight: 700;
    color: var(--writer-muted);
    letter-spacing: .04em;
}
.writer-head-text { min-width: 0; }
.writer-doc .writer-name {
    margin: 0 0 2px;
    font-size: 2rem;
    line-height: 1.15;
    letter-spacing: -0.012em;
}
.writer-doc .writer-title {
    margin: 0 0 2px;
    font-family: var(--writer-ui);
    font-size: .95rem; font-weight: 700;
    color: var(--writer-ink);
}
.writer-doc .writer-beat { margin: 0 0 6px; font-size: 1rem; color: var(--writer-muted); }
.writer-doc .writer-count {
    margin: 0;
    font-family: var(--writer-ui);
    font-size: .8125rem;
    color: var(--writer-muted);
}

@media (max-width: 34rem) {
    .writer-doc .writer-head { flex-direction: column; gap: 14px; }
    .writer-shot { flex-basis: 110px; width: 110px; height: 110px; }
    .writer-shot--none { font-size: 2.2rem; }
    .writer-doc .writer-name { font-size: 1.6rem; }
}

/* -- sections ------------------------------------------------------------- */

.writer-doc .writer-section { margin: 26px 0; }
.writer-doc .writer-h {
    margin: 0 0 10px;
    font-family: var(--writer-ui);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--writer-muted);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--writer-rule-soft);
}
.writer-doc .writer-sub {
    margin: -4px 0 12px;
    font-family: var(--writer-ui);
    font-size: .85rem;
    color: var(--writer-muted);
}

/* Contacts, as a spec list -- same shape as the assignment notice's fact
   panel, so the two pages read as one family. */
.writer-contacts { margin: 0; padding: 0; }
.writer-contact {
    display: grid;
    grid-template-columns: 7rem 1fr;
    gap: 0 1rem;
    padding: 9px 0;
    border-top: 1px solid var(--writer-rule-soft);
}
.writer-contact:first-child { border-top: 0; }
.writer-doc .writer-contact dt {
    margin: 0;
    font-family: var(--writer-ui);
    font-size: .68rem; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    line-height: 1.7;
    color: var(--writer-muted);
}
.writer-doc .writer-contact dd { margin: 0; font-size: 1rem; line-height: 1.5; word-break: break-word; }
.writer-contact-note {
    display: block;
    font-family: var(--writer-ui);
    font-size: .8rem;
    color: var(--writer-muted);
}
@media (max-width: 34rem) {
    .writer-contact { grid-template-columns: 1fr; gap: 2px 0; }
}

.writer-links { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.writer-links li { margin: 0; }
.writer-links a {
    display: inline-block;
    padding: 4px 11px;
    border: 1px solid var(--writer-rule);
    border-radius: 999px;
    font-family: var(--writer-ui);
    font-size: .82rem;
    text-decoration: none;
    background: #fff;
    transition: border-color .15s ease, background .15s ease;
}
.writer-links a:hover { border-color: var(--writer-blue); background: #f2f6fb; }

/* Current work. Given a left rule rather than a box: it is a list of things in
   progress, and a bordered card would make it look finished. */
.writer-projects { list-style: none; margin: 0; padding: 0; }
.writer-project {
    padding: 9px 0 9px 14px;
    border-left: 3px solid var(--writer-amber);
    margin-bottom: 10px;
    background: #fffdf6;
}
.writer-project-title { display: block; font-weight: 700; font-size: 1.03rem; }
.writer-project-note {
    display: block;
    margin-top: 2px;
    font-family: var(--writer-ui);
    font-size: .85rem;
    color: var(--writer-muted);
    line-height: 1.5;
}

.writer-stories { list-style: none; margin: 0; padding: 0; }
.writer-story { padding: 10px 0; border-top: 1px solid var(--writer-rule-soft); }
.writer-story:first-child { border-top: 0; }
.writer-story-title { font-weight: 700; font-size: 1.03rem; line-height: 1.35; text-decoration: none; }
.writer-story-title:hover { text-decoration: underline; }
.writer-story-dek { display: block; margin-top: 2px; font-size: .95rem; color: var(--writer-muted); line-height: 1.45; }
.writer-story-when {
    display: block; margin-top: 3px;
    font-family: var(--writer-ui);
    font-size: .76rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--writer-muted);
}

/* The standing commitments -- what turns this from a profile into something a
   reader can hold the paper to. */
.writer-doc .writer-section--creed {
    padding: 18px 22px;
    background: var(--writer-paper);
    border: 1px solid var(--writer-rule);
}
.writer-creed { margin: 0 0 12px; padding-left: 1.15em; }
.writer-doc .writer-creed li { margin-bottom: 8px; font-size: 1rem; line-height: 1.55; }
.writer-doc .writer-creed-foot { margin: 0; font-size: .9375rem; color: var(--writer-muted); }

.writer-doc .writer-foot {
    margin: 26px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--writer-rule);
    font-family: var(--writer-ui);
    font-size: .82rem;
    line-height: 1.6;
    color: var(--writer-muted);
}
.writer-foot-url { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .95em; word-break: break-all; }

/* -- the archive clipping ------------------------------------------------- */

/* A newspaper page is a tall, dense object. Shown small it reads as an
   artefact -- something to be picked up -- which is the right invitation; the
   reader is not meant to squint at it, they are meant to want to open it. */
.writer-clip { margin: 0; }
.writer-clip-btn {
    position: relative;
    display: block;
    width: 100%;
    max-width: 340px;
    padding: 10px;
    border: 1px solid var(--writer-rule);
    border-radius: 2px;
    /* Newsprint, not white -- the scan sits on it rather than floating. */
    background: #faf8f2;
    cursor: zoom-in;
    box-shadow: 0 1px 2px rgba(0,0,0,.06);
    transition: box-shadow .22s ease, transform .22s ease, border-color .22s ease;
}
.writer-clip-btn img { display: block; width: 100%; height: auto; }
.writer-clip-btn:hover,
.writer-clip-btn:focus-visible {
    transform: translateY(-2px);
    border-color: var(--writer-blue);
    box-shadow: 0 8px 22px rgba(22,79,139,.16);
    outline: none;
}

/* The affordance. Held at low opacity so the clipping is the thing being
   looked at, and brought up on hover -- it is a prompt, not a badge. */
.writer-clip-zoom {
    position: absolute;
    left: 50%;
    bottom: 18px;
    transform: translateX(-50%) translateY(6px);
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border-radius: 999px;
    background: rgba(22,24,26,.86);
    color: #fff;
    font-family: var(--writer-ui);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    opacity: 0;
    transition: opacity .22s ease, transform .22s ease;
    backdrop-filter: blur(2px);
}
.writer-clip-btn:hover .writer-clip-zoom,
.writer-clip-btn:focus-visible .writer-clip-zoom {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.writer-clip-cap {
    margin: 10px 0 0;
    max-width: 40rem;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--writer-muted);
}
.writer-clip-text { display: block; }
/* The attribution, always visible and never styled into invisibility. */
.writer-clip-credit {
    display: block;
    margin-top: 3px;
    font-family: var(--writer-ui);
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #7b8089;
}

/* -- the viewer ----------------------------------------------------------- */

.writer-lightbox {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2vh 2vw;
}
.writer-lightbox[hidden] { display: none; }
.writer-lightbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(12,13,15,.92);
    animation: writer-fade 200ms ease forwards;
}
.writer-lightbox-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    max-width: 1100px;
    max-height: 96vh;
    width: 100%;
    animation: writer-pop 260ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes writer-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes writer-pop {
    from { opacity: 0; transform: scale(.97) translateY(8px); }
    to   { opacity: 1; transform: none; }
}

/* The scan scrolls inside its own box, so the page behind never does and a
   zoomed broadsheet cannot push the layout around. */
.writer-lightbox-scroll {
    flex: 1 1 auto;
    overflow: auto;
    background: #fff;
    border-radius: 3px;
    -webkit-overflow-scrolling: touch;
}
.writer-lightbox-scroll img {
    display: block;
    width: 100%;
    height: auto;
    cursor: zoom-in;
}
/* Zoomed: past the container's width, so the browser's own scrolling takes
   over -- better than any pan this file could implement. */
.writer-lightbox-scroll img.is-zoomed { width: 190%; max-width: none; cursor: zoom-out; }

.writer-lightbox-close {
    position: absolute;
    top: -6px;
    right: -6px;
    z-index: 2;
    width: 38px;
    height: 38px;
    border: 0;
    border-radius: 50%;
    background: #fff;
    color: #16181a;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0,0,0,.4);
}
.writer-lightbox-close:hover { background: #f1f1ee; }

.writer-lightbox-cap {
    flex: none;
    margin: 10px 2px 0;
    font-family: var(--writer-ui);
    font-size: .85rem;
    line-height: 1.5;
    color: #e8e8e4;
}
.writer-lightbox-credit { display: block; margin-top: 2px; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: #a8adb5; }
.writer-lightbox-hint { display: block; margin-top: 6px; font-size: .72rem; color: #868c95; }

@media (max-width: 34rem) {
    .writer-clip-btn { max-width: 100%; }
    .writer-lightbox-close { top: 2px; right: 2px; }
}

@media (prefers-reduced-motion: reduce) {
    .writer-clip-btn,
    .writer-clip-zoom { transition: none; }
    .writer-clip-btn:hover, .writer-clip-btn:focus-visible { transform: none; }
    .writer-clip-btn:hover .writer-clip-zoom,
    .writer-clip-btn:focus-visible .writer-clip-zoom { opacity: 1; transform: translateX(-50%); }
    .writer-lightbox-backdrop, .writer-lightbox-panel { animation: none; opacity: 1; transform: none; }
}

/* Emphasis introduced by the bio's own *asterisk* rule. */
.writer-doc .writer-section em { font-style: italic; }

/* -- print ---------------------------------------------------------------- */
/* Somebody may well print this and put it in a file, which is a reasonable
   thing to do with a verification record. */
@media print {
    .header, .nav, nav, footer, #marquee, .osc-ticker, .osc-weather-ticker,
    aside, .pod-sidebar-card { display: none !important; }
    .writer-doc { max-width: none; }
    .writer-verify-shimmer { display: none; }
    .writer-lightbox { display: none !important; }
    .writer-clip-btn { max-width: none; border: 0; padding: 0; box-shadow: none; }
    .writer-clip-zoom { display: none; }
    .writer-doc .writer-verify::after { animation: none; }
    .writer-doc .writer-verify,
    .writer-section, .writer-story, .writer-project { break-inside: avoid; }
    /* The address is the point of the printed copy -- it is what somebody
       checks later against the page they are looking at. */
    .writer-doc a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; word-break: break-all; }
    .writer-doc a[href^="mailto"]::after,
    .writer-doc a[href^="tel"]::after { content: none; }
}
@page { margin: 18mm 16mm; }
