/*
 * The design system: components defined ONCE and consumed by both applications.
 *
 * Everything here was previously locked inside Blazor CSS isolation, which is the right
 * default for styling that belongs to one component and the wrong one for anything shared.
 * Two consequences showed up immediately and both were real:
 *
 *   Marketing.razor.css and PublicSite.razor.css were BYTE-IDENTICAL, 62 lines each. The
 *   first line of both said "Shared by the anonymous marketing page and its signed-in twin",
 *   so the intent to share was written down and the implementation duplicated it instead.
 *   Two copies of one organism drift the moment either page is restyled, and the two pages
 *   are required to look the same (contract item 32).
 *
 *   The form field and the primary button lived inside the feedback panel's stylesheet.
 *   Neither is specific to a feedback panel, and leaving them there is precisely why the
 *   next form in this product would have copied them a third time.
 *
 * Every value resolves through design-tokens (contract item 11). Nothing here carries a raw
 * colour, spacing or radius, and the gate greps for it.
 *
 * Generated into both wwwroot folders by scripts/build-design-system.py. Edit here, never
 * there.
 */

/* --- Atoms ------------------------------------------------------------------- */

.field {
    display: block;
    margin-bottom: var(--space-4);
}

.field span {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.field textarea,
.field input {
    width: 100%;
    padding: var(--space-3);
    font-family: var(--font-family-sans);
    font-size: var(--font-size-sm);
    color: var(--semantic-text);
    background-color: var(--semantic-surface);
    /* border-control, not border-strong: a field's edge is the only thing that says a field is
       there, so it is held to 3:1 (WCAG 1.4.11). border-strong measured 1.65:1 (E1-F3-S8). */
    border: var(--border-hairline) solid var(--semantic-border-control);
    border-radius: var(--radius-md);
    resize: vertical;
}

.button-primary {
    padding: var(--space-2) var(--space-5);
    border: none;
    border-radius: var(--radius-md);
    background-color: var(--semantic-primary);
    color: var(--semantic-on-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.button-primary:hover:not(:disabled) {
    background-color: var(--semantic-primary-hover);
}

.button-primary:disabled {
    background-color: var(--semantic-border-strong);
    cursor: not-allowed;
}

@media (max-width: 30rem) {
    .side-panel {
        width: 100%;
    }

    /* The panel is full width on a phone, so there is nowhere to move clear to. The
       panel carries its own close button, so hiding the stack loses nothing. */
    .fab-stack.panel-open {
        display: none;
    }
}

/* Shown INSTEAD of the thank-you when a note could not be kept. Every value resolves
   through a design token (contract item 11). */

/* An unhandled error, shown where it happened rather than as a blank page. Both
   applications styled this identically in their own app.css: the second instance the
   duplicate check found, on its first run. */
.blazor-error-boundary {
    padding: var(--space-4);
    border-radius: var(--radius-md);
    background-color: var(--semantic-danger-subtle);
    color: var(--semantic-danger);
}

/* --- Organisms: the marketing surface ----------------------------------------- */

.marketing-hero {
    padding: var(--space-6) 0 var(--space-7) 0;
    max-width: var(--measure-reading);
}

.marketing-hero h1 {
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-bold);
    /* --font-line was never a token. It resolved to nothing, so the largest
       heading on the marketing surface fell back to the browser default line
       height. The token check could not see it: its regex matched lowercase
       only, so --font-lineHeight-tight was truncated to --font-line in the
       DEFINED set, and the undefined name collided with that truncation.
       Tight, matching what app.css already uses for a heading of this size. */
    line-height: var(--font-lineHeight-tight);
    color: var(--color-brand-900);
}

.marketing-lede {
    margin-top: var(--space-4);
    font-size: var(--font-size-lg);
    color: var(--color-neutral-700);
}

/* The way in. A marketing page with no front door means the only people who can reach
 * the product are the ones who already know a gated URL by heart (v1.43.0). */
.marketing-actions {
    margin-top: var(--space-5);
}

.marketing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--measure-card-min), 1fr));
    gap: var(--space-5);
}

.marketing-card {
    padding: var(--space-5);
    border: var(--border-hairline) solid var(--color-neutral-200);
    border-radius: var(--radius-lg);
    background: var(--color-neutral-50);
}

.marketing-card h2 {
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--color-brand-700);
}

.marketing-card p {
    margin-top: var(--space-3);
    color: var(--color-neutral-700);
}

.marketing-contact {
    margin-top: var(--space-7);
    padding: var(--space-6);
    border-radius: var(--radius-lg);
    background: var(--color-brand-50);
    max-width: var(--measure-reading);
}

.marketing-contact h2 {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--color-brand-900);
}

.marketing-contact p {
    margin-top: var(--space-3);
    color: var(--color-neutral-700);
}

/* A table of records. Named for its shape rather than for the first screen that used it:
   it was `.capability-table` until v0.55.0, when the content inventory needed exactly the
   same table and the choice was to duplicate the rules under a second name or to admit the
   class had never been about capabilities. */
.data-table {
    width: 100%;
    margin-top: var(--space-5);
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

.data-table th,
.data-table td {
    padding: var(--space-3);
    text-align: left;
    border-bottom: var(--border-hairline) solid var(--semantic-border);
    vertical-align: top;
}

.data-table thead th {
    font-weight: var(--font-weight-semibold);
    color: var(--semantic-text-muted);
}

/* A table too wide for a phone scrolls inside its own box rather than widening the page
   (E6-F3-S2). The source to signed matter report has nine columns of counts, and squeezing
   them to fit would wrap every header into a stack of single words. The page itself keeps its
   width, so nothing else on it moves sideways. The markup makes the box focusable and names it,
   because a region that scrolls and cannot be reached by keyboard is one half the readers
   cannot scroll. */
.table-scroll {
    overflow-x: auto;
}

.table-scroll .data-table caption {
    text-align: left;
    font-weight: var(--font-weight-semibold);
    padding-bottom: var(--space-2);
}

.capability-always {
    color: var(--semantic-text-muted);
}

.capability-saved {
    margin-top: var(--space-4);
    color: var(--semantic-success);
    font-size: var(--font-size-sm);
}

.capability-readonly {
    margin-top: var(--space-4);
    color: var(--semantic-text-muted);
    font-size: var(--font-size-sm);
}

/* A row of things a reader can do to whatever the page is showing. Wraps rather than
   scrolling, because an action pushed off the edge of a narrow screen is an action that
   does not exist. */
.page-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

/* What a list says when there is nothing in it (E2-F9-S1), drawn as the reference build draws
   it: a bordered panel, a small icon tile, a heading, a sentence or two, and the next step.

   A PANEL RATHER THAN A SENTENCE because the empty list is usually the first thing a new reader
   meets on a page, and a muted line at the size of a footnote reads as a footnote. The panel is
   the same width as the table it stands in for, so the page does not change shape when the
   first row arrives.

   The text is held to a narrow measure inside it. A centred paragraph the full width of the
   content column is a line too long to read back to its start. */
.empty-state {
    display: grid;
    justify-items: center;
    gap: var(--space-4);
    margin-top: var(--space-4);
    margin-bottom: var(--space-4);
    padding: var(--space-7) var(--space-6);
    text-align: center;
    background-color: var(--semantic-surface);
    border: var(--border-hairline) solid var(--semantic-border);
    border-radius: var(--radius-lg);
}

.empty-state-icon {
    display: grid;
    place-items: center;
    width: var(--space-7);
    height: var(--space-7);
    border-radius: var(--radius-md);
    background-color: var(--semantic-primary-subtle);
    color: var(--semantic-primary);
}

.empty-state-heading {
    margin: 0;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
}

.empty-state-body {
    max-width: var(--measure-dialog);
    color: var(--semantic-text-muted);
}

.empty-state-body p {
    margin: 0 0 var(--space-3) 0;
}

.empty-state-body p:last-child {
    margin-bottom: 0;
}

.empty-state-note {
    max-width: var(--measure-dialog);
    margin: 0;
    color: var(--semantic-text-muted);
    font-size: var(--font-size-sm);
}

/* The one zero that is good news. Left-aligned and marked with the accent, as the reference
   draws the dashboard, so an all-clear cannot be mistaken for a list nobody has started: the
   two mean opposite things and a reader glancing at the page must not have to read the words to
   tell them apart. */
.empty-state--clear {
    justify-items: start;
    text-align: left;
    padding: var(--space-6);
    border-left: var(--border-marker) solid var(--semantic-accent);
}

.empty-state--clear .empty-state-icon {
    border-radius: var(--radius-pill);
    background-color: var(--semantic-accent);
    color: var(--semantic-text-inverse);
}

/* The setup checklist on a new firm's dashboard (E1-F5-S2), drawn as the reference build draws
   "Four things before you go live": a numbered sequence of bordered rows, each with a marker, a
   title, why it matters, and how far it has got.

   DONE AND NOT DONE DIFFER IN TWO WAYS, NEVER COLOUR ALONE. A finished row carries the accent
   marker and a tick where the number was; an unfinished one keeps a plain ring with its number
   in it and the strong border. A reader who cannot tell the accent from the border still reads
   a tick against a number, and a screen reader hears "Done" or "To do" before each title.

   An ordered list, because the order is part of what it says: the first task is first because
   every later one waits on it. */
.setup-checklist {
    margin-top: var(--space-5);
    margin-bottom: var(--space-6);
    max-width: var(--measure-reading);
}

.setup-eyebrow {
    margin: 0 0 var(--space-1) 0;
    color: var(--semantic-text-muted);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
}

.setup-steps {
    display: grid;
    gap: var(--space-3);
    margin: var(--space-4) 0;
    padding: 0;
    list-style: none;
}

.setup-step {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-4);
    align-items: start;
    padding: var(--space-5);
    background-color: var(--semantic-surface);
    border: var(--border-hairline) solid var(--semantic-border);
    border-left: var(--border-marker) solid var(--semantic-border-strong);
    border-radius: var(--radius-lg);
}

.setup-step p {
    margin: var(--space-1) 0 0 0;
}

.setup-step-marker {
    display: grid;
    place-items: center;
    width: var(--space-6);
    height: var(--space-6);
    border: var(--border-hairline) solid var(--semantic-border-strong);
    border-radius: var(--radius-pill);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
}

.setup-step--done {
    border-left-color: var(--semantic-accent);
}

.setup-step--done .setup-step-marker {
    border-color: var(--semantic-accent);
    background-color: var(--semantic-accent);
    color: var(--semantic-text-inverse);
}

.setup-step-title {
    margin: 0;
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
}

.setup-step-meta {
    color: var(--semantic-text-muted);
    font-size: var(--font-size-sm);
}

.setup-step-action {
    display: inline-block;
    margin-top: var(--space-2);
    font-weight: var(--font-weight-semibold);
}

/* Where a firm that has done nothing yet starts (E1-F5-S1). The one panel on the first-sign-in
   dashboard that asks for something, so it carries the primary tint and the other paragraphs
   around it do not. */
.setup-start {
    margin: var(--space-5) 0;
    padding: var(--space-5);
    max-width: var(--measure-reading);
    background-color: var(--semantic-primary-subtle);
    border: var(--border-hairline) solid var(--semantic-border);
    border-radius: var(--radius-lg);
}

.setup-start h3 {
    margin: 0 0 var(--space-2) 0;
    font-size: var(--font-size-lg);
}

/* Leaving (E1-F5-S5). The numbered steps on the leaving page reuse the setup checklist's rows,
   because both are "what happens, in order". These two are the parts the setup list has no
   use for.

   The PANEL closes the page with the one thing a leaving firm most wants to hear, which is that
   nothing will try to keep it, beside the way out. The accent marker sets it apart from the
   steps above it without the alarm a warning colour would carry: leaving is not an error.

   The BANNER is the dashboard's one line about it, shown only while notice stands, so a firm
   that has given notice is never left to remember the date on its own. */
.leaving-panel {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: center;
    margin: var(--space-6) 0;
    padding: var(--space-5);
    max-width: var(--measure-reading);
    background-color: var(--semantic-primary-subtle);
    border: var(--border-hairline) solid var(--semantic-border);
    border-left: var(--border-marker) solid var(--semantic-accent);
    border-radius: var(--radius-lg);
}

.leaving-panel p {
    flex: 1 1 var(--measure-card-min);
    margin: 0;
}

.leaving-banner {
    margin: var(--space-4) 0;
    padding: var(--space-3) var(--space-4);
    max-width: var(--measure-reading);
    background-color: var(--semantic-primary-subtle);
    border: var(--border-hairline) solid var(--semantic-border);
    border-left: var(--border-marker) solid var(--semantic-accent);
    border-radius: var(--radius-md);
}

/* INTERNAL, FULL STACK STAFF ONLY: the reveal schedule beside a firm's setup checklist
   (E1-F5-S3). The same firm at the same moment, from our side: which capabilities it has, which
   are arranged to arrive and when, and which checklist tasks that brings.

   DRAWN SO IT CANNOT BE MISTAKEN FOR CLIENT CONTENT. The notice at the top is the dark primary
   with inverse text, a treatment nothing a client sees carries, because a screenshot of the
   staff dashboard is exactly how this panel would reach a client if it looked like the rest of
   the page. The markup never reaches a client at all; this is for the staff member who shares
   their screen.

   The states differ by words first and colour second: every state is a sentence, and a change
   arranged for a date carries a calendar mark as well as its tint. */
.reveal-schedule {
    margin-top: var(--space-5);
    margin-bottom: var(--space-6);
    padding: var(--space-5);
    max-width: var(--measure-reading);
    background-color: var(--semantic-surface-sunken);
    border: var(--border-hairline) solid var(--semantic-border-strong);
    border-radius: var(--radius-lg);
}

.reveal-schedule-notice {
    margin: 0 0 var(--space-4) 0;
    padding: var(--space-3) var(--space-4);
    background-color: var(--semantic-primary-active);
    color: var(--semantic-text-inverse);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.reveal-state {
    display: inline-flex;
    gap: var(--space-1);
    align-items: center;
}

.reveal-state--arriving {
    color: var(--semantic-success);
}

.reveal-state--leaving {
    color: var(--semantic-warning);
}

.reveal-state--withheld {
    color: var(--semantic-text-muted);
}

.reveal-tasks {
    display: grid;
    gap: var(--space-2);
    margin: var(--space-3) 0;
    padding-left: var(--space-5);
}

.reveal-task {
    padding-left: var(--space-2);
    border-left: var(--border-marker) solid var(--semantic-accent);
}

.reveal-task--absent {
    border-left-color: var(--semantic-border-strong);
}

/* Text for a screen reader only. Used where the visual layout already labels a control
   (a column heading above an input) but the control itself would be announced bare. Not
   display:none, which removes it from the accessibility tree along with everything else. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}


/* An attorney's photograph on their public profile.

   The intrinsic width and height are on the element, not here, because the browser needs
   them before any stylesheet is applied in order to reserve the space. What CSS adds is
   that the reserved box scales with the column: a fixed 480 pixels on a phone is a
   photograph wider than the screen.

   object-fit keeps a portrait or a landscape original from being stretched into a square.
   A distorted face on the page somebody uses to decide whether to ring a solicitor is
   worse than no photograph. */
.attorney-photo {
    display: block;
    width: 100%;
    max-width: var(--measure-tooltip);
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--radius-md);
    margin-bottom: var(--space-4);
}

/* A regulator's badge in a site footer. Its intrinsic size is set by the regulator, who
   specifies a minimum, so nothing here scales it up: the constraint is a floor rather than a
   target, and enlarging a badge past the size its provider serves it at makes it blurred
   evidence of authorisation. */
.site-regulator-badge {
    display: block;
    max-width: 100%;
    height: auto;
    margin-top: var(--space-4);
}

/*
 * A verbatim value a reader may be asked to quote: an error reference, a route, a hostname.
 *
 * THE FIRST BASE-ELEMENT RULE IN THIS FILE, and it earns that. The management application loads
 * Bootstrap, whose default `code` colour fails WCAG AA contrast, and the site renderer styles
 * `code` not at all. So the same element read differently in the two applications and one of the
 * two was inaccessible.
 *
 * Nothing noticed for the same reason the scaffold error page survived: the only pages using
 * `code` were the two nobody looked at. axe found it on the first run of the audit that finally
 * reached them (tick 192), on a page whose whole purpose is to give somebody a reference to
 * quote, in a colour they may not be able to read.
 */
code {
  background: var(--semantic-surface-sunken);
  border: var(--border-hairline) solid var(--semantic-border);
  border-radius: var(--radius-sm);
  color: var(--semantic-text);
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
  padding: var(--space-1) var(--space-2);
}
