/*
 * ParkView portal — the whole stylesheet.
 *
 * One hand-written file, no framework, no build step (WORKPLAN M7: "single
 * lightweight CSS, no JS framework; server-rendered pages, mobile-usable").
 * The audience reads this on phones in two languages, one of which is
 * Cyrillic, so the type stack carries a Cyrillic-capable fallback.
 */

:root {
    --ink: #1c2321;
    --ink-muted: #5b6663;
    --paper: #ffffff;
    --wash: #f4f6f5;
    --line: #d9e0dd;
    --accent: #2f6b4f;        /* pine green — the building sits under Pirin */
    --accent-dark: #24523d;
    --error: #a32d2d;
    --radius: 6px;
}

*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    color: var(--ink);
    background: var(--wash);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "DejaVu Sans", sans-serif;
    font-size: 17px;
    line-height: 1.55;
}

/* --- Header ------------------------------------------------------------- */

.site-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.9rem 1.25rem;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
}

.brand {
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--ink);
    text-decoration: none;
}

.site-nav {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.site-nav a { color: var(--accent-dark); text-decoration: none; }
.site-nav a:hover { text-decoration: underline; }

.inline-form { display: inline; margin: 0; }

/* A submit button that reads as a link — used for logout, which must be a
   POST but should not look like a call to action. */
.linkish {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--accent-dark);
    cursor: pointer;
    text-decoration: none;
}
.linkish:hover { text-decoration: underline; }

.lang-switch { display: flex; gap: 0.35rem; margin: 0; }

.lang {
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.15rem 0.45rem;
    font: inherit;
    font-size: 0.85rem;
    color: var(--ink-muted);
    cursor: pointer;
}
.lang:hover { border-color: var(--accent); color: var(--accent-dark); }

.lang.current {
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    padding: 0.15rem 0.45rem;
    font-size: 0.85rem;
    background: var(--accent);
    color: var(--paper);
}

/* --- Layout ------------------------------------------------------------- */

.site-main {
    max-width: 62rem;
    margin: 0 auto;
    padding: 1.75rem 1.25rem 3rem;
}

.site-footer {
    max-width: 62rem;
    margin: 0 auto;
    padding: 1rem 1.25rem 2rem;
    color: var(--ink-muted);
    font-size: 0.9rem;
}

h1 { font-size: 1.9rem; line-height: 1.2; margin: 0 0 0.6rem; }
h2 { font-size: 1.25rem; margin: 0 0 0.4rem; }

.lede { font-size: 1.08rem; color: var(--ink-muted); }
.muted { color: var(--ink-muted); font-size: 0.95rem; }
/* The bracketed EUR-equivalent line under a BGN legacy row's Amount, and other
   small print (WORKPLAN §3 M9 item 7's `<span class="muted small">`). */
.small { font-size: 0.85rem; }

/* --- Landing page ------------------------------------------------------- */
/*
 * A full-bleed photograph with a single button on it. `templates/portal/home.html`
 * is standalone — it does not extend base.html — so nothing here inherits the
 * site header, footer or `.site-main` width, and nothing else on the site uses
 * these rules.
 */

.splash-body {
    margin: 0;
    /* The page never scrolls: the image is sized to the viewport, so a
     * scrollbar could only ever come from rounding. */
    overflow: hidden;
    background: var(--ink, #1c2321);
}

.splash {
    position: relative;
    /* `100dvh`, not `100vh`: on mobile Safari and Chrome `vh` is the viewport
     * with the address bar *hidden*, so a `100vh` image is taller than what is
     * actually on screen and the button sits below the fold until the user
     * scrolls — on a page built not to scroll. `dvh` tracks the real viewport.
     * The `100vh` line before it is the fallback for browsers without `dvh`. */
    height: 100vh;
    height: 100dvh;
    width: 100%;
    overflow: hidden;
}

.splash-image {
    width: 100%;
    height: 100%;
    /* Cover, so the photograph fills any shape of window; the building sits
     * centre-frame in the source, so centred cropping keeps it. */
    object-fit: cover;
    object-position: center;
    display: block;
}

/*
 * A scrim, not a tint. The photograph runs from near-white snow to near-black
 * pine, so neither white nor dark text is legible everywhere on it — and a
 * text shadow alone is not enough over the bright sky and sunlit peaks the
 * panel now sits on. This darkens only the top third, which reads as an
 * ordinary sky vignette rather than as an overlay, and it also gives the
 * language toggle in the same corner something to sit against.
 * `pointer-events: none` keeps it from swallowing the button beneath it.
 */
.splash::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.62) 0%,
        rgba(0, 0, 0, 0.38) 22%,
        rgba(0, 0, 0, 0) 52%
    );
    pointer-events: none;
    z-index: 1;
}

/*
 * The name and the way in, as one centred stack near the head of the image.
 *
 * The `top` offset has a floor of 4rem rather than scaling freely with the
 * viewport: the language toggle sits in the same corner of the frame and, at
 * its largest, occupies roughly the first 3.5rem. A panel that tracked `vh`
 * alone would ride up into it on a short landscape phone.
 */
.splash-panel {
    position: absolute;
    left: 50%;
    top: clamp(4rem, 12vh, 7.5rem);
    transform: translateX(-50%);
    z-index: 2;

    width: min(90vw, 40rem);
    text-align: center;
    color: #fff;
}

.splash-title {
    margin: 0 0 clamp(1rem, 3vh, 1.75rem);
    font-weight: 600;
    line-height: 1.05;
    /* Belt and braces with the scrim: the shadow carries the letterforms if a
     * tall crop ever puts the panel below the gradient, over the sunlit peaks
     * on either side of the building. */
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}

.splash-title-main,
.splash-title-sub {
    display: block;
}

.splash-title-main {
    font-size: clamp(2.4rem, 7vw, 4.5rem);
    letter-spacing: 0.01em;
}

.splash-title-sub {
    margin-top: 0.15em;
    font-size: clamp(1.1rem, 2.6vw, 1.8rem);
    font-weight: 400;
    /* Spaced out, the way a building's name is set on its own sign. */
    letter-spacing: 0.34em;
    /* Tracking is added after every letter *including the last*, so the box
     * centred by `text-align` is one space wider than the glyphs and the word
     * lands half a space left of true centre. Nudging right by half the
     * tracking puts it back. */
    text-indent: 0.17em;
    text-transform: uppercase;
    opacity: 0.92;
}

.splash-button {
    display: inline-block;
    padding: 0.85rem 2.75rem;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-decoration: none;
    white-space: nowrap;

    color: #fff;
    background: var(--accent, #2f6b4f);
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: var(--radius, 6px);
    /* The photograph is bright snow in places and near-black pine in others,
     * so the button cannot rely on the image for contrast. The shadow keeps
     * its edge legible wherever it lands. */
    box-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
}

.splash-button:hover,
.splash-button:focus {
    background: var(--accent-dark, #24523d);
    box-shadow: 0 3px 18px rgba(0, 0, 0, 0.55);
}

/* Keyboard users must be able to see where they are, and the default outline
 * disappears against a busy photograph. */
.splash-button:focus-visible,
.splash-lang-button:focus-visible {
    outline: 3px solid #fff;
    outline-offset: 3px;
}

/*
 * Language toggle, top right. It sits in the sky at every crop of this
 * photograph — the lightest, quietest part of the frame — so it is drawn as
 * translucent glass rather than as a solid control: present when looked for,
 * not competing with the building.
 *
 * The scrim above darkens this corner too, so these sit against it rather than
 * against raw sky; the shadow stays as the fallback for a crop that shifts the
 * gradient off them.
 */
.splash-lang {
    position: absolute;
    top: clamp(0.9rem, 2.5vh, 1.6rem);
    right: clamp(0.9rem, 2.5vw, 1.6rem);
    z-index: 2;

    display: flex;
    gap: 0.3rem;
    margin: 0;
}

.splash-lang-button,
.splash-lang-current {
    display: inline-block;
    padding: 0.28rem 0.6rem;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1.2;
    border-radius: var(--radius, 6px);
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
}

.splash-lang-button {
    color: #fff;
    background: rgba(0, 0, 0, 0.28);
    border: 1px solid rgba(255, 255, 255, 0.45);
    cursor: pointer;
    /* Buttons inherit the OS font stack rather than the page's without this. */
    font-family: inherit;
}

.splash-lang-button:hover {
    background: rgba(0, 0, 0, 0.45);
    border-color: rgba(255, 255, 255, 0.8);
}

/* The current language is stated, not offered — it is a <span>, not a button,
 * so there is nothing to click that would do nothing. */
.splash-lang-current {
    color: #fff;
    background: rgba(255, 255, 255, 0.22);
    border: 1px solid rgba(255, 255, 255, 0.75);
}

.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem;
    margin-top: 1.5rem;
}

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.1rem 1.25rem;
}
.card p { margin: 0; color: var(--ink-muted); }

.contact { margin-top: 2rem; }

/* --- Forms and buttons -------------------------------------------------- */

.button {
    display: inline-block;
    background: var(--accent);
    color: var(--paper);
    padding: 0.55rem 1.15rem;
    border: 0;
    border-radius: var(--radius);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}
.button:hover { background: var(--accent-dark); }

.stacked-form {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    max-width: 26rem;
}

.stacked-form label { display: block; font-weight: 600; margin-bottom: 0.25rem; }

.stacked-form input[type="text"],
.stacked-form input[type="password"],
.stacked-form input[type="email"] {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    font: inherit;
}

/* --- Notices ------------------------------------------------------------ */

.messages { list-style: none; max-width: 62rem; margin: 1rem auto 0; padding: 0 1.25rem; }
.messages li { padding: 0.6rem 0.9rem; border-radius: var(--radius); background: var(--paper); }

.notice {
    background: var(--paper);
    border: 1px solid var(--line);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
}

.error { color: var(--error); font-weight: 600; }

/* --- Tables ------------------------------------------------------------- */
/* Wide tables scroll inside their own container rather than making the whole
   page scroll sideways on a phone. */
.table-wrap { overflow-x: auto; background: var(--paper); border: 1px solid var(--line);
              border-radius: var(--radius); }

table.data { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
table.data.narrow { width: auto; min-width: 20rem; }
table.data th, table.data td { padding: 0.5rem 0.75rem; text-align: left;
                               border-bottom: 1px solid var(--line); vertical-align: top; }
table.data thead th { background: var(--wash); font-size: 0.85rem; text-transform: uppercase;
                      letter-spacing: 0.03em; color: var(--ink-muted); white-space: nowrap; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.wrap { max-width: 22rem; }

/* A request still awaiting a decision. */
tr.row-pending td { background: #fbf7e8; }

.button.small { padding: 0.25rem 0.6rem; font-size: 0.9rem; }

/* Figures that are placeholders, not real money. Deliberately styled as
   obviously unfinished — a plausible-looking wrong balance is worse than an
   evidently absent one on a site owners are asked to trust about money. */
.stacked-form textarea {
    width: 100%; padding: 0.5rem 0.6rem; border: 1px solid var(--line);
    border-radius: var(--radius); font: inherit;
}
.stacked-form span.muted, .stacked-form span.error { display: block; font-size: 0.9rem; }

/* --- Money ------------------------------------------------------------- */
/* Figures right-aligned and tabular so columns of amounts line up on the
   decimal point — the whole point of a statement is being scannable. */
table.data th.num, table.data td.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* An amount still owed. Deliberately not alarming red everywhere: red is
   reserved for genuinely overdue figures on the payment demand (M4). */
.owing { color: #8a4b1f; }
/* An overpayment. Three flats in the 2026 register are in credit. */
.credit { color: var(--accent-dark); }

table.data tr.total-row th, table.data tr.total-row td {
    border-top: 2px solid var(--line);
}

.notice.overdue { border-left-color: var(--error); }

.period-picker { display: inline-flex; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
.period-picker select {
    padding: 0.3rem 0.5rem; border: 1px solid var(--line);
    border-radius: var(--radius); font: inherit;
}

/* A voided payment stays on the statement, struck through, so the correction
   is visible rather than silently absent. */
table.data tr.voided td { text-decoration: line-through; opacity: 0.65; }
table.data tr.voided td strong { text-decoration: none; opacity: 1; }

/* --- Reconciliation ------------------------------------------------------ */
/* Green when the books and the statement agree exactly; the difference is
   shown in the warning colour otherwise. Exactly zero, not "close to zero" —
   the point of the exercise is that every cent is accounted for. */
.notice.reconciled { border-left-color: var(--accent); background: #f2f8f4; }
.notice.reconciled h2 { color: var(--accent-dark); }
.notice .difference { color: var(--error); }
.stacked-form.wide { max-width: 34rem; }
.stacked-form select, .stacked-form input[type="date"], .stacked-form input[type="number"] {
    width: 100%; padding: 0.5rem 0.6rem; border: 1px solid var(--line);
    border-radius: var(--radius); font: inherit;
}
table.data td form.inline-form input[type="text"] {
    padding: 0.2rem 0.4rem; border: 1px solid var(--line);
    border-radius: var(--radius); font: inherit; font-size: 0.9rem; width: 9rem;
}

/* --- Outbox and message previews (M6) ------------------------------------ */
/* Messages are plain text and are shown as composed — monospaced, wrapped, and
   scrollable rather than stretching the page, because a token link is a long
   unbroken string. */
pre.email-body {
    font-family: ui-monospace, "DejaVu Sans Mono", monospace;
    font-size: 0.85rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
    background: var(--wash);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.8rem;
    max-height: 32rem;
    overflow-y: auto;
}

/* The outbox filter row. */
form.filters { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: end; margin-bottom: 1rem; }
form.filters label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.9rem; }
form.filters select {
    padding: 0.35rem 0.5rem; border: 1px solid var(--line);
    border-radius: var(--radius); font: inherit;
}

/* A draft on the reminder preview: the summary is the control, so make it
   look like one. */
details > summary { cursor: pointer; color: var(--accent-dark); }

/* --- Grouped settings form (M7) ------------------------------------------ */
/* The site settings page is the one form where the fields are of genuinely
   different kinds — two switches that change what ninety owners can see about
   each other, and a block of bank details reprinted on every payment demand.
   Grouping them is not decoration: it stops the IBAN sitting in an undivided
   run of inputs directly beneath a visibility toggle. */
.stacked-form fieldset {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1rem 1.1rem 0.4rem;
    margin: 0 0 1.5rem;
}
.stacked-form legend {
    font-weight: 600;
    padding: 0 0.4rem;
}
.stacked-form fieldset > p.muted:first-of-type { margin-top: 0; }

/* A checkbox reads left-to-right: the box, then what it means. The label rule
   above makes every other label a block, which would put the text on its own
   line above the box and leave the two looking unrelated. */
.stacked-form p.check label {
    display: inline;
    font-weight: 600;
    margin-left: 0.4rem;
}
.stacked-form p.check span.muted { margin-left: 1.6rem; }
