/* CodeHeart. White paper, black ink - and the metal of a level, where one is shown. */

@import url("materials.css");

html {
    font-size: 100%;
}

body {
    margin: 0;
    background: #ffffff;
    color: #000000;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 1.0625rem;
    line-height: 1.65;
}

main {
    max-width: 34rem;
    margin: 0 auto;
    padding: 4rem 1.5rem 3rem;
}

h1 {
    margin: 0;
    font-size: 2rem;
    font-weight: normal;
    letter-spacing: 0.22em;
}

.motto {
    margin: 0.5rem 0 3.5rem;
    font-style: italic;
}

h2 {
    margin: 0 0 1.5rem;
    font-size: 1rem;
    font-weight: normal;
    letter-spacing: 0.16em;
}

section {
    margin-bottom: 3.5rem;
}

ul {
    margin: 1.5rem 0 0;
    padding-left: 1.2rem;
}

li {
    margin-bottom: 0.4rem;
}

/* Signing */

label {
    display: block;
}

input[type="text"],
input[type="email"] {
    width: 100%;
    box-sizing: border-box;
    margin-top: 0.3rem;
    padding: 0.5rem;
    border: 1px solid #000000;
    border-radius: 0;
    background: #ffffff;
    color: #000000;
    font-family: inherit;
    font-size: 1rem;
}

/* Every principle, checked individually - no blanket "accept all", so each
   one is its own row: checkbox and its own statement, wrapped together in
   one label so either can be clicked. */
.oath-checklist {
    margin-bottom: 3rem;
}

.oath-checkbox-item {
    display: flex;
    gap: 0.7rem;
    align-items: flex-start;
    margin-top: 1.1rem;
    cursor: pointer;
}

.oath-checkbox-item:first-child {
    margin-top: 0;
}

.oath-checkbox {
    margin-top: 0.3rem;
    flex-shrink: 0;
}

button {
    margin-top: 0.5rem;
    padding: 0.7rem 1.6rem;
    border: 1px solid #000000;
    border-radius: 0;
    background: #ffffff;
    color: #000000;
    font-family: inherit;
    font-size: 0.9rem;
    letter-spacing: 0.14em;
    cursor: pointer;
    transition: opacity 0.3s ease;
}

button:hover {
    background: #000000;
    color: #ffffff;
}

/* The only difference between a disabled and an enabled button is opacity -
   not colour, not a border change. Disabled also covers the moment a
   request is in flight after a submit, which reuses this same look. */
button[disabled] {
    cursor: default;
    opacity: 0.4;
}

.error {
    margin-top: 1.5rem;
    font-style: italic;
}

/* The introduction used to be one paragraph with a manual line break; it is
   now two paragraphs so the presentation engine can reveal them separately.
   Zero margin between them reproduces the same tight, single-line-break look
   the manual break gave it - not a new rhythm, the old one kept. */
.oath-introduction p {
    margin: 0;
}

/* ------------------------------------------------------------------ */
/* The oath page's presentation sequence                              */
/*                                                                     */
/* The base opacity:0 that hides these while html.js-presenting is set */
/* lives inline in oath.mustache, not here, for the same reason as the */
/* landing page: it has to apply before this file has necessarily even */
/* finished loading. What's here only matters once oath.js is already  */
/* running.                                                            */
/* ------------------------------------------------------------------ */

.js-presenting .oath-introduction p.ready,
.js-presenting .oath-principles li.ready {
    opacity: 1;
}

.js-presenting #signing,
.js-presenting .ceremony-welcome,
.js-presenting .ceremony-values,
.js-presenting .ceremony-continue {
    transition: opacity 0.4s ease;
}

.js-presenting #signing.visible,
.js-presenting .ceremony-welcome.visible,
.js-presenting .ceremony-values.visible,
.js-presenting .ceremony-continue.visible {
    opacity: 1;
}

/* Ceremony - what appears after a successful signing, on the oath page.
   .number and .download, once here, styled a page that no longer exists in
   this form; nothing in the templates has referenced either class since. */

.ceremony-welcome {
    font-size: 1.0625rem;
}

.ceremony-values {
    margin: 2.5rem 0 0;
}

.ceremony-values p {
    margin: 0 0 0.5rem;
}

.ceremony-continue {
    margin-top: 3rem;
}

#continue-link {
    text-decoration: none;
}

/* Footer */

footer {
    max-width: 34rem;
    margin: 0 auto;
    padding: 0 1.5rem 4rem;
    font-size: 0.8125rem;
}

a {
    color: #000000;
}

:focus-visible {
    outline: 2px solid #000000;
    outline-offset: 2px;
}

/* ------------------------------------------------------------------ */
/* Stage 1 - recognition                                              */
/*                                                                    */
/* Composed like the opening page of a book: centred, mostly empty,   */
/* and read from the top down in one pass. Every rule here exists to  */
/* put air between four sentences.                                    */
/* ------------------------------------------------------------------ */

.landing {
    max-width: 30rem;
    padding-top: 9rem;
    padding-bottom: 0;
    text-align: center;
}

.emblem {
    display: block;
    width: 3.25rem;
    height: 3.25rem;
    margin: 0 auto 4.5rem;
}

.landing h1 {
    font-size: 1.75rem;
    letter-spacing: 0.42em;
    /* letter-spacing adds a trailing gap; this pulls the line back to centre */
    text-indent: 0.42em;
    line-height: 1.4;
}

.creed {
    margin: 5rem 0 0;
}

.creed p,
.climax {
    line-height: 1.5;
}

.creed p {
    margin: 0 0 2.25rem;
}

.creed p:last-child {
    margin-bottom: 0;
}

/* Reads as a continuation of the same sequence, so the gap above it matches
   the rhythm between the lines in .creed rather than starting a new block. */
.climax {
    margin: 2.25rem 0 0;
}

/*
   The one spacing change requested for this page: a little more air between
   "We are... code_heart" and the button below it. Was 6rem.
*/
.threshold {
    margin: 7.5rem 0 0;
}

.button {
    display: inline-block;
    padding: 0.85rem 1.9rem;
    border: 1px solid #000000;
    color: #000000;
    text-decoration: none;
    font-size: 0.8125rem;
    letter-spacing: 0.2em;
    text-indent: 0.2em;
}

.button:hover {
    background: #000000;
    color: #ffffff;
}

.landing-footer {
    padding-top: 7rem;
    text-align: center;
}

/* ------------------------------------------------------------------ */
/* The presentation sequence                                          */
/*                                                                     */
/* The base opacity:0 that hides these elements while html.js-presenting */
/* is set lives inline in index.mustache, not here - it has to apply     */
/* before this file has necessarily even finished loading. What's here  */
/* only matters once presentation.js is already running: how a line      */
/* looks once it is ready to be typed into, and how the button and      */
/* footer look once they fade in.                                       */
/* ------------------------------------------------------------------ */

.js-presenting .creed p.ready,
.js-presenting .climax.ready {
    opacity: 1;
}

.js-presenting .threshold,
.js-presenting .landing-footer {
    transition: opacity 0.4s ease;
}

.js-presenting .threshold.visible,
.js-presenting .landing-footer.visible {
    opacity: 1;
}

/* A thin blinking caret at the point where text is being written.
   animation-duration is set inline, from cursorBlinkMs in config.json. */
.caret {
    display: inline-block;
    width: 1px;
    height: 1em;
    margin-left: 1px;
    background: #000000;
    vertical-align: -0.1em;
    animation: caret-blink step-end infinite;
}

@keyframes caret-blink {
    50% {
        opacity: 0;
    }
}

/*
   Reduced motion is handled inline, in index.mustache, in the same place
   that decides whether js-presenting is set at all - there is nothing left
   here that needs overriding.
*/

/* ------------------------------------------------------------------ */
/* Stage 3 - commitment, and the public registry                      */
/* ------------------------------------------------------------------ */

.recorded,
.registry {
    padding-top: 6rem;
}

.notice {
    margin-bottom: 2.5rem;
    font-style: italic;
}

.record {
    margin: 3rem 0;
}

.record dt {
    font-size: 0.75rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
}

.record dd {
    margin: 0.35rem 0 1.75rem;
    font-size: 1.0625rem;
}

.registry-id {
    font-size: 1.375rem;
    letter-spacing: 0.06em;
    font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    font-variant-numeric: lining-nums tabular-nums;
}

.entered {
    margin-bottom: 1rem;
}

/*
   A level, as a medal beside its name. The page stays black on white; only
   the medal carries the material, from materials.css.
*/

.level-badge {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    margin: 2.5rem 0;
}

.medal {
    flex: none;
    position: relative;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    background: radial-gradient(circle at 34% 28%,
        var(--metal-light), var(--metal) 55%, var(--metal-dark));
    box-shadow:
        inset 0 0 0 3px rgba(255, 255, 255, 0.25),
        inset 0 0 0 4px var(--metal-dark),
        0 0.4rem 0.9rem -0.4rem rgba(0, 0, 0, 0.45);
}

.medal::after {
    content: attr(data-level);
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffffff;
    font-size: 1.25rem;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.pearl .medal {
    background:
        radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.9), transparent 45%),
        var(--iridescence);
}

.badge-label {
    display: block;
    font-size: 0.75rem;
    letter-spacing: 0.2em;
    color: var(--metal-dark);
}

.badge-title {
    display: block;
    font-size: 1.25rem;
}

.status-revoked {
    color: #a3221b;
}

/* ------------------------------------------------------------------ */
/* The gate - between the public site and the realm                   */
/*                                                                     */
/* The one page that is not white paper. Night outside, a signboard    */
/* green and cream, and two doors that swing open when the account is  */
/* opened. Silver waits on the other side.                             */
/* ------------------------------------------------------------------ */

.gate-page {
    --night: #0f1f19;
    --board: #18352a;
    --cream: #f3ead6;
    --cream-muted: #c9bfa8;
    min-height: 100vh;
    background:
        radial-gradient(ellipse at 50% 0%, rgba(243, 234, 214, 0.10), transparent 60%),
        var(--night);
    color: var(--cream);
    overflow-x: hidden;
}

.gate {
    position: relative;
    max-width: 30rem;
    margin: 0 auto;
    padding: 5rem 1.5rem 4rem;
}

.gate-content {
    position: relative;
    z-index: 1;
    padding: 2.5rem 2rem;
    background: var(--board);
    border: 1px solid rgba(243, 234, 214, 0.25);
    box-shadow:
        inset 0 0 0 4px var(--board),
        inset 0 0 0 5px rgba(243, 234, 214, 0.18),
        0 2rem 4rem -2rem rgba(0, 0, 0, 0.8);
}

.gate-kicker {
    margin: 0 0 1.25rem;
    font-size: 0.75rem;
    letter-spacing: 0.3em;
    color: var(--cream-muted);
}

.gate-title {
    margin: 0 0 1rem;
    font-size: 1.625rem;
    letter-spacing: 0.01em;
    line-height: 1.3;
}

.gate-lead {
    margin: 0 0 1.5rem;
    color: var(--cream-muted);
}

.gate-lead strong {
    color: var(--cream);
    font-weight: normal;
}

.gate-badge {
    margin: 1.75rem 0 2rem;
}

.gate-badge .badge-label {
    color: var(--cream-muted);
}

.gate-form label {
    color: var(--cream);
}

.gate-form input[type="password"] {
    box-sizing: border-box;
    width: 100%;
    margin-top: 0.4rem;
    padding: 0.7rem 0.8rem;
    border: 1px solid rgba(243, 234, 214, 0.35);
    background: rgba(0, 0, 0, 0.25);
    color: var(--cream);
    font: inherit;
}

.gate-form input[type="password"]:focus {
    outline: 2px solid var(--cream-muted);
    outline-offset: 1px;
}

.gate-hint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.8125rem;
    color: var(--cream-muted);
}

.gate-page .error {
    color: #f2b8a8;
}

.gate-button {
    display: inline-block;
    padding: 0.85rem 1.9rem;
    border: 1px solid var(--cream);
    background: transparent;
    color: var(--cream);
    font: inherit;
    font-size: 0.8125rem;
    letter-spacing: 0.2em;
    text-decoration: none;
    cursor: pointer;
}

.gate-button:hover,
.gate-button:focus-visible {
    background: var(--cream);
    color: var(--board);
}

.gate-button:disabled {
    opacity: 0.5;
    cursor: default;
}

/* The doors stand behind the board and open outward once it is gone. */

.gate-doors {
    position: fixed;
    inset: 0;
    z-index: 2;
    display: flex;
    pointer-events: none;
    visibility: hidden;
}

.gate-door {
    flex: 1;
    background:
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.18) 0 2px, transparent 2px 46px),
        var(--board);
    border: 1px solid rgba(243, 234, 214, 0.2);
    transition: transform 1.2s cubic-bezier(0.7, 0, 0.3, 1) 0.3s;
}

.gate-door.left  { transform-origin: left center; }
.gate-door.right { transform-origin: right center; }

/* Closed for a moment, then swung away to reveal the realm's light. */
.gate-opening .gate-doors {
    visibility: visible;
    perspective: 1200px;
    background: radial-gradient(circle at 50% 50%, #fffaf0, #c9bfa8);
}

.gate-opening .gate-content {
    opacity: 0;
    transition: opacity 0.3s ease;
}

.gate-opening .gate-door.left  { transform: rotateY(-100deg); }
.gate-opening .gate-door.right { transform: rotateY(100deg); }

@media (prefers-reduced-motion: reduce) {
    .gate-door { transition: none; }
}
