/* Passphrase generator. Depends on page-shell.css for the hero/heading scale. */

/* ---- page measure ---------------------------------------------------------- */

/* Same width as /tools/, because they are siblings under the same menu entry and
   seeing one at 760px next to the other at the container width reads as a bug
   rather than a decision. Nothing on this page is capped below the container:
   the hero, the prose, the generator and the table all run to the edge of their
   card, so no card is left half empty.

   The usual argument against a long measure is that a 1,200px line is hard to
   track back to the next one. Two things answer it here: the text is justified,
   which keeps the right edge steady, and the paragraphs are short — the plain
   layer averages under ten words a sentence. */

.passphrase-hero .page-kicker i { margin-right: 0.35rem; }

/* ---- the output ------------------------------------------------------------ */

.pp-output-wrap {
    background: var(--card-bg, #161b22);
    border: 1px solid var(--border, #30363d);
    border-radius: 12px;
    padding: 1.5rem;
    margin: 0 0 1.5rem;
}

/* The generated phrase. Monospace so l/1/I and 0/O are distinguishable when a
   reader transcribes it, and `user-select: all` so one click takes the whole
   thing rather than a single word. */
.pp-output {
    display: block;
    font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
    font-size: clamp(1.05rem, 3.2vw, 1.7rem);
    line-height: 1.5;
    color: var(--accent, #00ff9d);
    word-break: break-word;
    overflow-wrap: anywhere;
    user-select: all;
    min-height: 2.6em;
}

.pp-error {
    color: #f85149;
    font-size: 0.9rem;
    margin: 0.5rem 0 0;
}

.pp-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 1.1rem;
}

.pp-btn {
    font: inherit;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--text-primary, #e6edf3);
    background: transparent;
    border: 1px solid var(--border, #30363d);
    border-radius: 8px;
    padding: 0.55rem 1.1rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    transition: all 0.2s ease;
}

.pp-btn:hover { border-color: var(--accent, #00ff9d); color: var(--accent, #00ff9d); }
.pp-btn:focus-visible { outline: 2px solid var(--accent, #00ff9d); outline-offset: 2px; }

.pp-btn-primary {
    background: rgba(0, 255, 157, 0.12);
    border-color: rgba(0, 255, 157, 0.4);
    color: var(--accent, #00ff9d);
}

.pp-copied { font-size: 0.85rem; color: var(--accent, #00ff9d); }

/* ---- controls -------------------------------------------------------------- */

.pp-controls {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 1.25rem;
    margin-bottom: 1.5rem;
}

.pp-field {
    border: 1px solid var(--border, #30363d);
    border-radius: 10px;
    padding: 1rem 1.1rem;
    margin: 0;
}

.pp-field legend,
.pp-field > label {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted, #8b949e);
    padding: 0 0.3rem;
}

.pp-radio {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0;
    font-size: 0.92rem;
    cursor: pointer;
}

.pp-radio small { color: var(--text-muted, #8b949e); font-size: 0.78rem; }

.pp-field input[type="range"] { width: 100%; margin: 0.8rem 0 0.4rem; accent-color: var(--accent, #00ff9d); }
.pp-field select {
    width: 100%;
    margin-top: 0.6rem;
    padding: 0.45rem 0.6rem;
    font: inherit;
    font-size: 0.9rem;
    color: var(--text-primary, #e6edf3);
    background: var(--card-bg, #161b22);
    border: 1px solid var(--border, #30363d);
    border-radius: 6px;
}

.pp-hint { font-size: 0.78rem; color: var(--text-muted, #8b949e); margin: 0.5rem 0 0; line-height: 1.45; }

/* ---- entropy readout ------------------------------------------------------- */

.pp-strength {
    border-left: 3px solid var(--accent, #00ff9d);
    padding: 0.85rem 1.1rem;
    background: rgba(0, 255, 157, 0.05);
    border-radius: 0 8px 8px 0;
}

.pp-strength-main { margin: 0; font-size: 1.05rem; }
.pp-strength-detail { margin: 0.3rem 0 0; font-size: 0.85rem; color: var(--text-muted, #8b949e); }

/* ---- no-JS notice ---------------------------------------------------------- */

.pp-noscript {
    border: 1px solid #d29922;
    border-radius: 10px;
    padding: 1.1rem 1.25rem;
    margin-bottom: 1.5rem;
    background: rgba(210, 153, 34, 0.07);
}

.pp-noscript p { margin: 0 0 0.7rem; font-size: 0.93rem; line-height: 1.6; }
.pp-code {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.82rem;
    background: var(--card-bg, #161b22);
    border: 1px solid var(--border, #30363d);
    border-radius: 8px;
    padding: 0.9rem;
    overflow-x: auto;
    margin: 0;
}

/* ---- prose ----------------------------------------------------------------- */

.pp-explain { margin-top: 2.5rem; }
.pp-explain h2 { font-size: 1.4rem; margin-bottom: 1.2rem; }
.pp-explain h3 { font-size: 1.05rem; margin: 1.8rem 0 0.6rem; color: var(--accent, #00ff9d); }
.pp-explain p { font-size: 1rem; line-height: 1.75; margin: 0 0 1rem; }
.pp-explain code {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.87em;
    padding: 0.1em 0.35em;
    border-radius: 4px;
    background: rgba(110, 118, 129, 0.15);
}
.pp-post-link { margin-top: 1.6rem; padding-top: 1.1rem; border-top: 1px solid var(--border, #30363d); }
.pp-post-link i { color: var(--accent, #00ff9d); margin-right: 0.35rem; }

@media (max-width: 700px) {
    .pp-output-wrap { padding: 1.1rem; }
    .pp-controls { grid-template-columns: 1fr; gap: 1rem; }
}

/* ---- justified prose ------------------------------------------------------- */

/* Matches `.post-content p` and `.profile-bio p` elsewhere on the site. This page is
   mostly reading and sits one link from the post it belongs to, so it should set the
   same way.

   Two deliberate exclusions. The generated phrase is a value, not prose: justification
   stretches inter-word space, and with the space separator that would misrepresent the
   thing the reader is about to transcribe. Headings stay ragged because a justified
   two-line heading reads as a mistake. */
.page-passphrase .page-intro,
.page-passphrase .pp-noscript p,
.page-passphrase .pp-explain p,
.page-passphrase .pp-hint {
    text-align: justify;
}

/* The hints sit inside ~230px control cards, where justification has too little room
   to distribute and opens visible gaps instead. Hyphenation gives it somewhere to go;
   `lang` is set on <html> in both editions, so the dictionary is the right one. */
.page-passphrase .pp-hint {
    hyphens: auto;
    -webkit-hyphens: auto;
}

/* ---- attack-cost table ----------------------------------------------------- */

/* The table is five rows by four columns of mostly short strings, so it fits on a
   phone if the label column is allowed to wrap and the wrapper is allowed to scroll.
   `overflow-x: auto` is the fallback, not the plan: a table that needs scrolling to
   read the last column has already lost the comparison it exists to make. */
.pp-table-wrap {
    overflow-x: auto;
    margin: 0 0 1.2rem;
    -webkit-overflow-scrolling: touch;
}

.pp-crack-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.87rem;
    min-width: 30rem;
}

.pp-crack-table caption {
    caption-side: top;
    text-align: left;
    font-size: 0.8rem;
    color: var(--text-muted, #8b949e);
    padding-bottom: 0.5rem;
}

.pp-crack-table th,
.pp-crack-table td {
    padding: 0.55rem 0.7rem;
    border-bottom: 1px solid var(--border, #30363d);
    vertical-align: top;
    text-align: left;
}

.pp-crack-table thead th {
    font-weight: 600;
    color: var(--accent, #00ff9d);
    border-bottom-width: 2px;
    white-space: nowrap;
}

.pp-crack-table thead th small {
    display: block;
    font-weight: 400;
    font-size: 0.78rem;
    color: var(--text-muted, #8b949e);
}

/* The row headers are the only long strings in the table; everything else is a
   duration of three or four words. Give them the room and keep the cells compact. */
.pp-crack-table tbody th {
    font-weight: 400;
    line-height: 1.45;
    white-space: normal;
    min-width: 14rem;
}

/* Who uses this scheme, under the scheme's name rather than beside it: the label is
   the widest thing in the table and an em dash in the middle of it wrapped badly. */
.pp-crack-table tbody th small {
    display: block;
    font-size: 0.8rem;
    color: var(--text-muted, #8b949e);
}

.pp-crack-table tbody td {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pp-crack-table tbody tr:last-child th,
.pp-crack-table tbody tr:last-child td { border-bottom: none; }

/* ---- sources --------------------------------------------------------------- */

/* Specific enough to beat `.pp-explain p`'s bottom margin without `!important`:
   this line is a label for the list under it, not a paragraph of its own. */
.pp-explain .pp-sources-intro { margin-bottom: 0.4rem; font-weight: 600; }

.pp-sources {
    margin: 0 0 1rem;
    padding-left: 1.2rem;
    font-size: 0.88rem;
    line-height: 1.6;
}

.pp-sources li { margin-bottom: 0.55rem; }
.pp-sources a { text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 700px) {
    .pp-crack-table { font-size: 0.82rem; min-width: 26rem; }
    .pp-crack-table tbody th { min-width: 11rem; }
}

/* ---- the plain layer ------------------------------------------------------- */

/* The one line under the strength readout that explains it without jargon. */
.pp-strength-plain {
    margin: 0.6rem 0 0;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--text-muted, #8b949e);
}

.pp-explain .pp-steps-intro { margin-bottom: 0.4rem; font-weight: 600; }

/* Numbered, roomy, and not justified: these are three instructions to act on, and
   they are the only place on the page where the reader is told what to do. */
.pp-steps {
    margin: 0 0 1.4rem;
    padding-left: 1.4rem;
    line-height: 1.7;
}

.pp-steps li { margin-bottom: 0.5rem; }

/* ---- collapsed technical layer --------------------------------------------- */

/* Everything the page used to lead with lives in here. Closed by default, open on
   one click, no JavaScript involved — <details> is the element for exactly this, and
   it keeps the material reachable by keyboard and screen reader instead of hiding it
   behind a script that may not run. */
.pp-details {
    margin: 0 0 1.6rem;
    border-left: 2px solid var(--border, #30363d);
    padding-left: 1rem;
}

.pp-details > summary {
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--accent, #00ff9d);
    padding: 0.3rem 0;
    list-style: none;
}

/* Replace the default marker with one that states which way it will move. */
.pp-details > summary::-webkit-details-marker { display: none; }
.pp-details > summary::before {
    content: "\25b8";                 /* right-pointing triangle */
    display: inline-block;
    margin-right: 0.5rem;
    transition: transform 0.15s ease;
}
.pp-details[open] > summary::before { transform: rotate(90deg); }

.pp-details > summary:hover { text-decoration: underline; }
.pp-details > summary:focus-visible {
    outline: 2px solid var(--accent, #00ff9d);
    outline-offset: 3px;
    border-radius: 3px;
}

.pp-details > *:not(summary) { font-size: 0.95rem; }
.pp-details > p:first-of-type { margin-top: 0.7rem; }
.pp-details > p:last-child { margin-bottom: 0.2rem; }

@media (prefers-reduced-motion: reduce) {
    .pp-details > summary::before { transition: none; }
}

/* ---- plain row labels in the table ----------------------------------------- */

/* The plain label leads; the scheme name and who ships it follow in smaller type, so
   a reader can find their row without knowing what PBKDF2 is. */
.pp-crack-table tbody th { font-weight: 600; }
.pp-crack-table tbody th small { font-weight: 400; }

/* ---- real cases in the intro ----------------------------------------------- */

/* Three breaches, each one sentence of setup and one of consequence. They are a
   list rather than three paragraphs because a reader scanning the page should be
   able to see that there are three, and which is which, without reading them. */
.pp-cases {
    margin: 0 0 1.2rem;
    padding: 0;
    list-style: none;
}

.pp-cases li {
    border-left: 2px solid var(--border, #30363d);
    padding: 0.15rem 0 0.15rem 1rem;
    margin-bottom: 1rem;
    line-height: 1.7;
    text-align: justify;
}

.pp-cases li strong { display: block; margin-bottom: 0.15rem; }
.pp-cases li strong a { color: var(--accent, #00ff9d); text-decoration: none; }
.pp-cases li strong a:hover { text-decoration: underline; }

/* A citation that follows a sentence, rather than a list entry: small, and set off
   so it reads as provenance and not as part of the claim. */
.pp-cite {
    font-size: 0.82rem;
    white-space: nowrap;
    color: var(--text-muted, #8b949e);
    text-decoration: underline;
    text-underline-offset: 2px;
}
