/*
Theme Name: MFA Musavirlik
Description: Custom theme recreating the MFA Musavirlik bespoke design system, ported from the ASP.NET Core Blazor original for a direct side-by-side comparison.
Author: Recep Gultekin
Version: 1.0
Text Domain: mfamusavirlik
*/
/* Global design tokens + base typography for the public site. Loaded before
   app.css (which only carries Blazor-scaffold overrides), so these are the
   base layer every page inherits. Self-hosted Barlow + Barlow Condensed
   (SIL OFL 1.1) — no external font CDN request; url() paths are relative to
   this file's own location (wwwroot/), not the page URL, so they are NOT
   prefixed with "/". Turkish character coverage (ş ğ ı İ ö ü ç and their
   capitals) verified directly against each file's cmap table before
   committing to this pairing — see PROJECT_CONTEXT.md §7. Replaces the
   earlier single-family Archivo choice: this pairing (a condensed display
   face for headings + its regular-width sibling for body/labels) is the
   one used by the "MFA Musavirlik Mockup - standalone.html" reference the
   client pointed to as the target look. */
@font-face {
    font-family: 'Barlow';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('assets/fonts/barlow-400.woff2') format('woff2');
}

@font-face {
    font-family: 'Barlow';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('assets/fonts/barlow-600.woff2') format('woff2');
}

@font-face {
    font-family: 'Barlow Condensed';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('assets/fonts/barlow-condensed-600.woff2') format('woff2');
}

:root {
    /* Brand navy — unchanged, confirmed independently against the reference
       mockup's own rendered (not default-tool-template) accent color. */
    --color-accent: #2c5580;
    /* Darkened 2026-07-25 (was #1c3d5c) after pulling oncanmimarlik.com's
       actual live CSS: its hover states commit fully to near-black
       (background-color: #000 on filter-button/link hover), not a subtle
       tint shift — a technique already half-adopted here (see the
       .pill-group hover comment below) but not pushed far enough. Kept as
       a dark step of the SAME navy hue (same R:G:B ratio as --color-accent,
       just darker) rather than jumping to literal black — this project
       committed to navy specifically, not gray/black, after real
       competitor research (PROJECT_CONTEXT.md §1/§7); this is "commit to
       navy harder," not "abandon navy for the reference's actual hue." */
    --color-accent-dark: #12263a;
    /* Cool light gray, not warm cream — the reference mockup's own
       background tone. Supersedes an earlier warm-paper pass made before
       the client shared this mockup; match the reference over that
       earlier guess. */
    --color-bg: #f2f2f3;
    --color-surface: #e9e9ea;
    --color-surface-card: #ffffff;
    --color-text: #1d1f20;
    --color-text-muted: rgba(29, 31, 32, 0.62);
    /* Hairline border/divider color used throughout the reference (card
       borders, blueprint-frame borders, table-style grid lines). */
    --color-divider: rgba(29, 31, 32, 0.16);
    /* A lighter, desaturated step of the brand navy — used for eyebrow
       labels and lede copy in the reference, distinct from the plain
       neutral --color-text-muted used for card meta lines. */
    --color-accent-muted: #416180;
    --font-heading: 'Barlow Condensed', system-ui, sans-serif;
    --font-body: 'Barlow', system-ui, sans-serif;
    --font-base: var(--font-body);
    --radius: 0;
    --shadow-sm: 0 1px 3px rgba(29, 31, 32, 0.15);
    --content-width: 1100px;
    --space-section: clamp(2.5rem, 5vw, 4.5rem);
    /* A confident deceleration curve for the site's "settle" moments (page
       load, hero draw-in, scroll reveal) — replaces plain ease-out with
       something more deliberate for a more premium feel, per the
       frontend-design skill's "leverage motion deliberately" guidance.
       Durations are unchanged; only the curve shape. */
    --ease-settle: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html {
    /* Sticky-footer base: the shell below stretches to at least the full
       viewport height so .site-footer never sits above a dead strip of
       page background on short-content pages — it fixed a real reported
       layout bug where the footer floated mid-page on the empty-state
       References page instead of anchoring to the bottom. */
    height: 100%;
    /* .page-hero and .section-band deliberately break out of the content
       column via width:100vw + margin-inline:calc(50% - 50vw) (the
       standard full-bleed technique) — but 100vw includes the vertical
       scrollbar's own width on desktop browsers, which the visible page
       area does not. On any page tall enough to actually need a vertical
       scrollbar, those elements end up wider than the visible viewport by
       exactly the scrollbar's width, producing a spurious horizontal
       scrollbar too (caught directly from a real screenshot, not a
       theoretical concern). This is the standard, safe guard for that
       specific gotcha — it doesn't mask a real horizontal-content bug
       elsewhere, since nothing on this site is meant to scroll sideways. */
    overflow-x: hidden;
    /* Vertical scrollbar hidden per explicit request (2026-07-25) — a
       real trade-off was flagged first (this removes the only persistent
       visual cue that more content exists below the fold on platforms
       that don't show an auto-hiding overlay scrollbar) and the request
       stood. Scrolling itself still works fully — wheel, touch, keyboard
       (Page Down/Space/arrow keys), and a screen reader's own navigation
       are all untouched; only the scrollbar's own track/thumb rendering
       is suppressed. Cross-browser: Firefox uses scrollbar-width, old
       Edge/IE used -ms-overflow-style, everything Chromium/WebKit-based
       needs the ::-webkit-scrollbar rule below (Firefox/Edge have no
       equivalent pseudo-element, so this isn't redundant duplication). */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

    html::-webkit-scrollbar {
        display: none;
    }

body {
    margin: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-body);
    line-height: 1.6;
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0 0 0.75rem;
}

h1 {
    /* Uppercase via CSS over naturally-cased authored text (not
       ALL-CAPS content strings) — matches the reference exactly:
       screen readers/translation/SEO see "Projects", the page shows
       "PROJECTS". Same convention applies to .card-title below. */
    text-transform: uppercase;
    font-size: clamp(2rem, 4vw + 1rem, 2.75rem);
    /* Tighter than the shared -0.01em on h2-h4 — a more confident,
       considered condensed-display setting at the page's largest,
       most load-bearing text, not applied uniformly everywhere. */
    letter-spacing: -0.02em;
}

h2 {
    font-size: clamp(1.35rem, 2vw + 1rem, 1.75rem);
}

/* Plain, low-key "back" link for public pages one level deep (currently
   just ProjectDetail). Was reusing admin.css's .admin-back (same visual
   treatment) because tokens.css was mid-edit by a concurrent design pass
   when this page was first built — that's resolved now, so this page gets
   its own public-facing class instead of borrowing admin-styled naming. */
.back-link {
    display: inline-block;
    margin-bottom: 1.25rem;
    color: var(--color-text-muted);
    font-size: 0.9rem;
    text-decoration: none;
}

    .back-link:hover {
        color: var(--color-accent);
    }

/* "Eyebrow" label — small-caps technical/title-block-style tag above a
   heading. On top-level pages it's numbered ("01 · Hakkımızda"), a real
   drawing-sheet-index convention pulled directly from the reference. */
.eyebrow {
    display: block;
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-accent-muted);
    /* Tighter than before — the label now reads as one unit with its
       rule directly below, rather than floating with equal space above
       and below it. */
    margin-bottom: 0.4rem;
}

/* Hairline rule under a page eyebrow, spanning the content width — replaces
   the earlier dashed "tick-rule" motif, which read as a stray fragment
   rather than a deliberate mark (flagged directly as ugly) and the
   full-bleed navy hero band that replaced it (superseded in turn once the
   reference mockup showed neither exists there — every page just sits on
   the plain background with a numbered eyebrow + hairline + heading). */
.page-eyebrow-rule {
    height: 1px;
    background: var(--color-divider);
    /* More generous than before (was 1.75rem) — a deliberate breath
       between the label+rule unit and the headline, rather than uniform
       spacing throughout; the label/rule/heading now read as three
       distinct rhythmic steps instead of one flat block. */
    margin: 0 0 2.25rem;
}

/* Short divider under an in-page sub-heading (e.g. "Team" inside About). */
.section-rule {
    height: 1px;
    width: 100%;
    background: var(--color-divider);
    margin: 0.6rem 0 1.75rem;
}

main {
    flex: 1;
    width: 100%;
    max-width: var(--content-width);
    margin-inline: auto;
    padding: var(--space-section) 1rem 3.5rem;
    /* One deliberate page-load moment, not scattered effects everywhere —
       the content settles in rather than snapping into place. Respects
       prefers-reduced-motion below. */
    animation: fade-in-up 0.4s var(--ease-settle) both;
}

@keyframes fade-in-up {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    main {
        animation: none;
    }
}

p {
    color: var(--color-text);
    max-width: 68ch;
}

/* Credit line for the hero video (About.razor's .page-hero) — the hero
   itself is edge-to-edge and aria-hidden (purely ambient), so this plain
   caption is the one place the admin-entered caption text actually
   surfaces. Deliberately not inside .page-hero itself (which is
   overflow:hidden and full-bleed) — sits in normal document flow right
   below it, same treatment a photo credit gets under a hero image. */
.page-hero__caption {
    margin: 0.5rem 0 1.75rem;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* Deliberate, not just "nothing rendered" — a real message with visual
   weight for any page with no admin-entered content yet. Never fabricated
   content, only this. Given the same bordered-box + corner-mark language
   as .blueprint-frame below (two marks, diagonal, not four — a lighter
   echo appropriate to a text block rather than an image) so an empty
   section reads as a designed part of the system, not a leftover
   fallback line. */
.empty-state {
    position: relative;
    color: var(--color-text-muted);
    font-style: italic;
    padding: 1.25rem 1.5rem;
    margin-top: 1rem;
    border: 1px solid var(--color-divider);
}

    .empty-state::before,
    .empty-state::after {
        content: "";
        position: absolute;
        width: 11px;
        height: 11px;
        pointer-events: none;
        background-image:
            linear-gradient(var(--color-divider), var(--color-divider)),
            linear-gradient(var(--color-divider), var(--color-divider));
        background-repeat: no-repeat;
        background-size: 1px 100%, 100% 1px;
        background-position: 5px 0, 0 5px;
    }

    .empty-state::before {
        top: -6px;
        left: -6px;
    }

    .empty-state::after {
        bottom: -6px;
        right: -6px;
    }

/* ---------------------------------------------------------------------
   Whole-page empty state (PageEmptyState.razor) — see that file for the
   real, screenshot-verified problem this fixes: a lone small box near the
   top of an otherwise-empty page left acres of flat dead space above the
   footer (worst on References). Centers within whatever room main{flex:1}
   leaves below the page header, at a deliberately larger scale than the
   inline .empty-state above (bigger corner ticks, a real icon, generous
   padding) so an empty page reads as one considered composition instead of
   a stub. Same corner-mark construction as .blueprint-frame, just sized up.
   ------------------------------------------------------------------- */
.page-empty-state {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    text-align: center;
    flex: 1;
    min-height: clamp(240px, 34vh, 380px);
    margin-top: 1.5rem;
    padding: 3rem 1.5rem;
    border: 1px solid var(--color-divider);
    background-image:
        linear-gradient(var(--color-divider) 1px, transparent 1px),
        linear-gradient(90deg, var(--color-divider) 1px, transparent 1px);
    background-size: 28px 28px;
}

.page-empty-state > .corner {
    position: absolute;
    width: 16px;
    height: 16px;
    color: var(--color-divider);
}

    .page-empty-state > .corner::before,
    .page-empty-state > .corner::after {
        content: "";
        position: absolute;
        background: currentColor;
    }

    .page-empty-state > .corner::before { left: 7px; top: 0; width: 1px; height: 100%; }
    .page-empty-state > .corner::after { top: 7px; left: 0; width: 100%; height: 1px; }

.page-empty-state > .corner.tl { top: -8px; left: -8px; }
.page-empty-state > .corner.tr { top: -8px; right: -8px; }
.page-empty-state > .corner.bl { bottom: -8px; left: -8px; }
.page-empty-state > .corner.br { bottom: -8px; right: -8px; }

.page-empty-state__icon {
    color: var(--color-accent);
    opacity: 0.5;
}

.page-empty-state p {
    margin: 0;
    max-width: 32ch;
    color: var(--color-text-muted);
    font-style: italic;
}

/* ---------------------------------------------------------------------
   Section band — a full-bleed alternate-tint band for an in-page section,
   breaking up a single flat scroll into distinct rhythmic steps (a real gap
   found against oncanmimarlik.com/tr/profil's own "Biz" → "Ekibimiz" pacing,
   which alternates background tint between sections; this site's pages
   currently sit on one identical flat --color-bg from header to footer with
   nothing marking where one section ends and the next begins). Uses the
   existing --color-surface token already used elsewhere in this system
   (blueprint-frame placeholders, partner avatars) — not a new color, and
   explicitly not a dark band (see PROJECT_CONTEXT.md: the client chose the
   light system over dark bands). Same full-bleed technique as .page-hero.
   ------------------------------------------------------------------- */
.section-band {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    background: var(--color-surface);
    padding: var(--space-section) 1rem;
}

.section-band__inner {
    max-width: var(--content-width);
    margin-inline: auto;
}

a {
    color: var(--color-accent);
    transition: color 0.15s ease;
}

/* ---------------------------------------------------------------------
   Blueprint frame + corner marks — the site's one recurring signature
   motif (see PROJECT_CONTEXT.md §1's "carry the blueprint/drafting-tool
   visual language through the whole site" direction), pulled from the
   reference mockup's own implementation: a bordered frame, and four small
   registration/fiducial "+" ticks bleeding off each corner, exactly like
   alignment marks on a technical drawing. Applied by ResponsiveImage.razor
   to every content image, real or placeholder, so it reads as one
   consistent system rather than a "missing image" fallback only.
   ------------------------------------------------------------------- */
.blueprint-frame {
    position: relative;
    /* Deliberately NOT overflow:hidden — the corner marks below bleed half
       outside this box on purpose (top/left: -6px etc.) and would get
       clipped otherwise; a real bug caught in QA screenshots. object-fit
       already keeps the real <img> itself from overflowing its own box. */
    border: 1px solid var(--color-divider);
}

.blueprint-frame img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Placeholder state only (no image uploaded yet): a graph-paper grid tinted
   toward the brand navy via mix-blend-mode, with a centered line-icon. */
.blueprint-frame--placeholder {
    background-color: var(--color-surface);
    background-image:
        linear-gradient(var(--color-divider) 1px, transparent 1px),
        linear-gradient(90deg, var(--color-divider) 1px, transparent 1px);
    background-size: 22px 22px;
}

    .blueprint-frame--placeholder::after {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        background: var(--color-accent);
        mix-blend-mode: color;
    }

.blueprint-frame__icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: var(--color-accent);
    opacity: 0.45;
}

/* Small category/type tag, overlaid on the frame's bottom-left corner —
   used by Projects. A sibling of the image/placeholder inside the same
   .blueprint-frame, not a separate chip below the text. */
.blueprint-frame__tag {
    position: absolute;
    left: 0;
    bottom: 0;
    z-index: 1;
    background: var(--color-accent);
    color: #fff;
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.25rem 0.55rem;
}

.blueprint-frame > .corner {
    position: absolute;
    width: 11px;
    height: 11px;
    color: var(--color-divider);
    /* color added alongside the existing position properties so the hover
       escalation below (pale divider-gray -> solid navy) actually animates
       instead of snapping. */
    transition: top 0.2s ease, left 0.2s ease, right 0.2s ease, bottom 0.2s ease, color 0.2s ease;
}

    .blueprint-frame > .corner::before,
    .blueprint-frame > .corner::after {
        content: "";
        position: absolute;
        background: currentColor;
    }

    .blueprint-frame > .corner::before {
        left: 5px;
        top: 0;
        width: 1px;
        height: 100%;
    }

    .blueprint-frame > .corner::after {
        top: 5px;
        left: 0;
        width: 100%;
        height: 1px;
    }

.blueprint-frame > .corner.tl { top: -6px; left: -6px; }
.blueprint-frame > .corner.tr { top: -6px; right: -6px; }
.blueprint-frame > .corner.bl { bottom: -6px; left: -6px; }
.blueprint-frame > .corner.br { bottom: -6px; right: -6px; }

/* Hover: corner marks pull outward slightly (camera-focus-bracket feel) and
   both the frame border AND the corner-mark color itself commit fully to
   solid navy — was accent-on-border only, with the corner ticks staying
   pale divider-gray even on hover; escalated per the "commit harder on
   interaction, like a confident solid-fill hover instead of a subtle
   tint" direction (oncanmimarlik.com's own buttons/links flip to solid
   black on hover — same commitment, this site's navy instead of a new
   hue). Purely additive states layered on the base system above. */
@media (hover: hover) {
    .blueprint-frame:hover {
        border-color: var(--color-accent-dark);
    }

    .blueprint-frame:hover > .corner {
        color: var(--color-accent-dark);
    }

    .blueprint-frame:hover > .corner.tl { top: -9px; left: -9px; }
    .blueprint-frame:hover > .corner.tr { top: -9px; right: -9px; }
    .blueprint-frame:hover > .corner.bl { bottom: -9px; left: -9px; }
    .blueprint-frame:hover > .corner.br { bottom: -9px; right: -9px; }
}

/* Reduced-motion override for .blueprint-frame > .corner (both the
   position transition and the color transition just added above) already
   lives further down, alongside the hero's own reduced-motion block —
   not duplicated here. */

/* ---------------------------------------------------------------------
   Lightbox trigger — an invisible full-cover button layered over any
   .blueprint-frame image that opts in via ResponsiveImage's Lightbox
   parameter (see that component's own doc comment for why placeholders
   never get one — there's nothing larger to show). wwwroot/lightbox.js
   finds these via event delegation on document, not a per-element
   listener bound at load — so it keeps working on grid content that
   project-filter.js swaps in later, with no re-init step needed between
   the two scripts.
   ------------------------------------------------------------------- */
.lightbox-trigger {
    position: absolute;
    inset: 0;
    z-index: 2;
    border: 0;
    margin: 0;
    padding: 0;
    background: transparent;
    cursor: zoom-in;
    -webkit-tap-highlight-color: transparent;
}

    .lightbox-trigger:focus-visible {
        outline: 2px solid var(--color-accent);
        outline-offset: -2px;
    }

/* ---------------------------------------------------------------------
   Lightbox overlay — built entirely by wwwroot/lightbox.js on first use;
   there's no static markup for it in any Razor file. The frame reuses
   .blueprint-frame's own corner-mark construction (the script adds that
   exact class + the four <i class="corner ..."> children) so the enlarged
   image reads as the same system, not a generic modal look bolted on.
   ------------------------------------------------------------------- */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    padding: 4rem 3.5rem;
    background: color-mix(in srgb, var(--color-text) 82%, transparent);
    opacity: 0;
    transition: opacity 0.2s var(--ease-settle);
}

    .lightbox-overlay[hidden] {
        display: none;
    }

    .lightbox-overlay.is-open {
        opacity: 1;
    }

.lightbox-overlay__frame {
    flex: 0 1 auto;
    min-height: 0;
    background: var(--color-surface-card);
    transform: scale(0.97);
    transition: transform 0.2s var(--ease-settle);
}

    .lightbox-overlay.is-open .lightbox-overlay__frame {
        transform: scale(1);
    }

.lightbox-overlay__img {
    display: block;
    max-width: min(88vw, 1100px);
    max-height: 74vh;
    width: auto;
    height: auto;
}

.lightbox-overlay__caption {
    flex: 0 0 auto;
    margin: 0;
    max-width: 60ch;
    text-align: center;
    font-size: 0.82rem;
    color: var(--color-bg);
}

    .lightbox-overlay__caption:empty {
        display: none;
    }

.lightbox-overlay__close,
.lightbox-overlay__nav {
    position: fixed;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border: 1px solid rgba(246, 244, 240, 0.32);
    background: transparent;
    color: var(--color-bg);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

    /* Same solid-fill commitment as the other hover escalations on this
       page — transparent-to-solid-navy, not a faint tint. */
    @media (hover: hover) {
        .lightbox-overlay__close:hover,
        .lightbox-overlay__nav:hover {
            background: var(--color-accent-dark);
            border-color: var(--color-accent-dark);
        }
    }

    .lightbox-overlay__close:focus-visible,
    .lightbox-overlay__nav:focus-visible {
        outline: 2px solid var(--color-bg);
        outline-offset: 2px;
    }

.lightbox-overlay__close {
    top: 1.25rem;
    right: 1.25rem;
}

.lightbox-overlay__nav--prev {
    left: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
}

.lightbox-overlay__nav--next {
    right: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
}

    .lightbox-overlay__nav[hidden] {
        display: none;
    }

@media (max-width: 640px) {
    .lightbox-overlay {
        padding: 4.5rem 0.75rem 3.5rem;
    }

    .lightbox-overlay__nav--prev { left: 0.4rem; }
    .lightbox-overlay__nav--next { right: 0.4rem; }
}

@media (prefers-reduced-motion: reduce) {
    .lightbox-overlay,
    .lightbox-overlay__frame {
        transition: none;
    }
}

/* ---------------------------------------------------------------------
   Filter-swap transition — see wwwroot/project-filter.js. A plain opacity
   fade on the stable wrapper Projects.razor renders around whichever
   branch is currently showing (grid, filtered-empty message, or the
   very-first empty state) — the script toggles .is-filtering around its
   fetch+swap, this rule just supplies the transition.
   ------------------------------------------------------------------- */
[data-filter-target] {
    transition: opacity 0.15s ease;
}

    [data-filter-target].is-filtering {
        opacity: 0;
    }

@media (prefers-reduced-motion: reduce) {
    [data-filter-target] {
        transition: none;
    }
}

/* ---------------------------------------------------------------------
   Page frame — a second, larger-scale echo of the exact corner-mark
   construction above, this time framing the whole viewport rather than
   a single image. Desktop only (this site's hard mobile-first constraint
   means the primary viewport has no room to spend on a purely decorative
   frame — see PROJECT_CONTEXT.md §1). This is the direct, literal
   execution of the project's own stated differentiator: "carrying the
   blueprint/drafting-tool visual language through the whole site as a
   recurring motif, which neither competitor does at all" (PROJECT_
   CONTEXT.md §1) — ties the per-image corner marks, the About hero's
   large internal marks, and now the page itself into one multi-scale
   system instead of three unrelated details. Two marks only (diagonal),
   not four — restraint scales down as the device scales up: boldest on
   images (four), lighter on empty-state blocks (two, see above), lightest
   here since it persists across the whole page rather than one element.
   Fixed position (stays put while scrolling, like a real drawing sheet's
   border), pointer-events:none, and pure decoration — no aria role needed
   since it conveys nothing a screen reader or keyboard user would need. */
@media (min-width: 1024px) {
    body::before,
    body::after {
        content: "";
        position: fixed;
        z-index: 1;
        width: 18px;
        height: 18px;
        pointer-events: none;
        background-image:
            linear-gradient(var(--color-divider), var(--color-divider)),
            linear-gradient(var(--color-divider), var(--color-divider));
        background-repeat: no-repeat;
        background-size: 1px 100%, 100% 1px;
        background-position: 8px 0, 0 8px;
    }

    body::before {
        top: 20px;
        left: 20px;
    }

    body::after {
        bottom: 20px;
        right: 20px;
    }
}

/* ---------------------------------------------------------------------
   Card grids (Projects, Team) — plain image-then-text stacks, no boxed/
   shadowed card panel around the whole unit. Matches the reference: only
   the image gets the blueprint-frame treatment; the title/meta below it
   sit directly on the page background. Removed an earlier white-card +
   shadow + hover-lift + colored-top-border treatment once the reference
   showed none of that exists there.
   ------------------------------------------------------------------- */
.team-grid, .project-grid {
    display: grid;
    gap: 1.75rem;
    grid-template-columns: 1fr;
    list-style: none;
    padding: 0;
    margin: 0;
}

@media (min-width: 640px) {
    .team-grid, .project-grid {
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    }
}

.team-card, .project-card {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.card-title {
    font-family: var(--font-heading);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    margin: 0;
    font-size: 1.15rem;
}

/* The project listing's card-title wraps an <a> to the detail page (the
   cover image's own click area is the lightbox trigger instead — see
   Projects.razor's comment on why the two never compete for the same
   click). Inherit the heading's own color/weight rather than the global
   a{color:var(--color-accent)} rule, so a linked title doesn't visually
   read as "just a link" among plain-text card titles elsewhere (team,
   partners) — only the hover state gives away that it's interactive. */
.card-title a {
    color: inherit;
    text-decoration: none;
}

    .card-title a:hover,
    .card-title a:focus-visible {
        /* Darker step, not the base accent — matches the site's other
           hover states committing fully on interaction rather than a
           subtle tint shift (see --color-accent-dark's own doc comment). */
        color: var(--color-accent-dark);
    }

.card-meta {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin: 0;
}

.team-card p, .project-card p {
    color: var(--color-text-muted);
    font-size: 0.92rem;
    margin: 0;
}

/* ---------------------------------------------------------------------
   References — a plain bordered grid of company names, no images, no
   shadow; a shared-hairline table look (border-top/left on the grid,
   border-right/bottom on each cell, so adjoining lines never double up).
   ------------------------------------------------------------------- */
.reference-grid {
    display: grid;
    grid-template-columns: 1fr;
    list-style: none;
    padding: 0;
    margin: 0;
    border-top: 1px solid var(--color-divider);
    border-left: 1px solid var(--color-divider);
}

@media (min-width: 640px) {
    .reference-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

.reference-card {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 9rem;
    padding: 1.5rem;
    border-right: 1px solid var(--color-divider);
    border-bottom: 1px solid var(--color-divider);
}

    .reference-card h2 {
        font-family: var(--font-body);
        font-weight: 600;
        font-size: 0.85rem;
        letter-spacing: 0.03em;
        text-transform: uppercase;
        color: var(--color-text-muted);
        margin: 0;
    }

    .reference-card p {
        margin: 0.35rem 0 0;
        font-size: 0.78rem;
        color: var(--color-text-muted);
    }

    /* Replaces the plain <p> above when a reference links to a real
       project — same size/position, but a real link needs its own
       interactive-state treatment instead of inheriting the muted,
       deliberately-uninteractive look of plain reference-card text. */
    .reference-card__project-link {
        display: inline-block;
        margin: 0.35rem 0 0;
        font-size: 0.78rem;
        font-weight: 600;
        color: var(--color-accent);
    }

        .reference-card__project-link:hover,
        .reference-card__project-link:focus-visible {
            color: var(--color-accent-dark);
        }

/* ---------------------------------------------------------------------
   Partners — a directory list (monogram avatar + name + tag), not a card
   grid; hairline row dividers only.
   ------------------------------------------------------------------- */
.partner-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border-top: 1px solid var(--color-divider);
}

.partner-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 0;
    border-bottom: 1px solid var(--color-divider);
}

.partner-row__avatar {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-surface);
    border: 1px solid var(--color-divider);
    color: var(--color-text-muted);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.9rem;
}

/* Same 3rem slot as .partner-row__avatar (the monogram fallback) — for a
   real uploaded logo instead. mfa_responsive_image()'s .blueprint-frame has
   no width of its own (by design: project/team cards size it via their grid
   column), so without this wrapper it just fills the flex row — a real bug
   caught via a screenshot, not something a lint/build check would surface. */
.partner-row__logo {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
}

.partner-row__name {
    flex: 1 1 auto;
    min-width: 0;
}

    .partner-row__name strong {
        display: block;
        font-family: var(--font-heading);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.01em;
        font-size: 1rem;
    }

.partner-row__tag {
    flex: 0 0 auto;
    border: 1px solid var(--color-divider);
    color: var(--color-text-muted);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.35rem 0.7rem;
}

/* ---------------------------------------------------------------------
   Pill group — shared segmented-button styling for the Projects category
   filter and the header language switcher (see MainLayout.razor.css).
   Plain <a> links so both work with zero JS under this app's static-SSR-
   only render mode; aria-current="page" marks the active pill.
   ------------------------------------------------------------------- */
.pill-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.pill-group a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px — matches the site's touch-target baseline everywhere else
       (.btn, .site-nav-disclosure__toggle, .lightbox-overlay__close/__nav)
       — this was the one real gap found by cross-checking against a
       responsive-design skill's "44x44px minimum" rule: both real,
       frequently-tapped mobile controls that use this class (the header's
       TR/EN toggle and the Projects category filter) were sitting at 36px. */
    min-height: 2.75rem;
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--color-divider);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

    .pill-group a[aria-current="page"] {
        background: var(--color-accent);
        border-color: var(--color-accent);
        color: #fff;
    }

    /* Solid --color-accent-dark fill on hover, not the earlier light 6%
       tint — commits fully the way oncanmimarlik.com's own buttons/links
       flip to solid black on hover, rather than a subtle color shift.
       Deliberately the DARKER navy step (not the same --color-accent the
       already-selected pill uses) so hovering a pill never looks
       identical to it already being active — hover reads as "about to
       commit further," one step past the resting selected state. */
    @media (hover: hover) {
        .pill-group a:not([aria-current="page"]):hover {
            background: var(--color-accent-dark);
            border-color: var(--color-accent-dark);
            color: #fff;
        }
    }

/* ---------------------------------------------------------------------
   Page hero — real autoplaying background video (2026-07-24), on the
   About/Hakkımızda page only (the site's front door). Replaces an earlier
   animated blueprint-motif SVG placeholder that existed specifically
   because no real office footage existed yet; that placeholder is gone
   now that real footage does (see About.razor for the video markup).
   ------------------------------------------------------------------- */
.page-hero {
    position: relative;
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    /* Pulls the hero flush against the header, canceling exactly the top
       padding main() adds below — same --space-section token, so this
       stays correct if that token's clamp() values ever change. */
    margin-top: calc(-1 * var(--space-section));
    margin-bottom: var(--space-section);
    height: clamp(200px, 30vw, 360px);
    overflow: hidden;
    background: var(--color-bg);
}

.page-hero__video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Hides the whole band, not just the video's motion — a user who has
   opted out of motion never has autoplaying video start in the first
   place, rather than starting and then being paused after the fact. */
@media (prefers-reduced-motion: reduce) {
    .page-hero {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .blueprint-frame > .corner {
        transition: none;
    }
}

/* ---------------------------------------------------------------------
   Scroll-triggered reveal — see wwwroot/reveal.js. The hidden state only
   ever applies under .reveal-js (added by that script); without it, or
   under prefers-reduced-motion, or if IntersectionObserver is missing,
   every [data-reveal] element is just plainly visible, no JS dependency
   for correctness. Builds on the same fade-in-up language main() already
   uses elsewhere on this site rather than a different motion vocabulary.
   ------------------------------------------------------------------- */
.reveal-js [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.5s var(--ease-settle), transform 0.5s var(--ease-settle);
    transition-delay: var(--reveal-delay, 0s);
}

.reveal-js [data-reveal].is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Stagger by position within each grid/list's own direct children — one
   shared rule covers project/team/reference/partner items generically. */
.reveal-js [data-reveal]:nth-child(2) { --reveal-delay: 0.06s; }
.reveal-js [data-reveal]:nth-child(3) { --reveal-delay: 0.12s; }
.reveal-js [data-reveal]:nth-child(4) { --reveal-delay: 0.18s; }
.reveal-js [data-reveal]:nth-child(5) { --reveal-delay: 0.24s; }
.reveal-js [data-reveal]:nth-child(6) { --reveal-delay: 0.3s; }
.reveal-js [data-reveal]:nth-child(n+7) { --reveal-delay: 0.36s; }

@media (prefers-reduced-motion: reduce) {
    .reveal-js [data-reveal] {
        opacity: 1;
        transform: none;
        transition: none;
    }
}


/* ===== Ported from MainLayout.razor.css (site header/nav/footer chrome) ===== */
/* Shared public-site chrome. Mobile-first: the nav lives inside a collapsed
   <details> with the summary as a tap target; the 768px breakpoint below
   forces it open as a horizontal bar. CSS isolation scopes these to this
   component's own markup (header/nav/footer), never @Body page content.

   .site-header/.site-footer are flex children of <body> (see tokens.css'
   sticky-footer flex column) — neither needs its own height rule, they just
   participate in that column alongside <main>'s flex: 1. */
.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    flex: 0 0 auto;
    gap: 0.5rem 1.5rem;
    padding: 0.85rem 1.25rem;
    background: var(--color-bg);
    /* Anchors the mobile dropdown panel below (.site-nav's absolute
       positioning, see the mobile-first rule further down) to this
       element's own box, not <body> or the viewport. */
    position: relative;
    /* A plain hairline, not a bold accent band — matches the reference's
       own lighter header treatment (superseding an earlier heavier,
       3px-navy-border pass made before that reference was available). */
    border-bottom: 1px solid var(--color-divider);
}

.site-header__logo {
    display: inline-flex;
    flex: 0 0 auto;
    transition: opacity 0.15s ease;
}

    .site-header__logo:hover {
        opacity: 0.8;
    }

    .site-header__logo svg {
        /* Raised from 48px (2026-07-24) to fit the full 4-line lockup
           (MFA / MÜŞAVİRLİK / MÜHENDİSLİK / MİMARLIK) legibly — see
           MainLayout.razor's doc comment on the logo markup. */
        height: 68px;
        width: auto;
        display: block;
    }

.site-nav-disclosure {
    flex: 0 0 auto;
}

/* Mobile dropdown panel — a real bug found via a live phone screenshot
   (not just an emulated viewport): .site-nav-disclosure previously held
   BOTH the toggle and the expanded nav as one ordinary flex item with no
   width of its own, so opening it just grew that one narrow, right-
   anchored item taller in place — a big empty gap under the logo, with
   the menu floating short and right-aligned instead of a real full-width
   panel. Taking .site-nav out of flow and anchoring it to .site-header's
   own box (position: relative above) fixes this without touching the
   toggle button's position at all: the <details> disclosure's own flex-
   item box stays exactly as tall as the closed summary, and the nav opens
   as a proper edge-to-edge dropdown underneath instead of growing in
   place. Reset back to normal in-flow layout at the desktop breakpoint
   below, where the nav is a plain horizontal row, not a dropdown. */
.site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-bg);
    border-top: 1px solid var(--color-divider);
    box-shadow: var(--shadow-sm);
    padding: 0 1.25rem 1.25rem;
    z-index: 20;
}

/* Toggle: sharp-cornered button look, disclosure triangle removed, and a
   44px minimum touch target per the mobile UX baseline. */
.site-nav-disclosure__toggle {
    list-style: none;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    background: var(--color-accent);
    color: var(--color-bg);
    border-radius: var(--radius);
    font-weight: 800;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.15s ease;
}

    .site-nav-disclosure__toggle:hover {
        background: var(--color-accent-dark);
    }

    .site-nav-disclosure__toggle::-webkit-details-marker {
        display: none;
    }

    /* ::-webkit-details-marker above only covers WebKit/Blink; the standard
       ::marker pseudo-element (broadly supported, including Firefox) covers
       the rest. Both are harmless no-ops in browsers that don't match them. */
    .site-nav-disclosure__toggle::marker {
        content: "";
    }

.site-nav ul {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

/* Scoped to "> ul a" specifically, not just ".site-nav a" — the language
   pill toggle (.site-nav__lang-wrap) is also a descendant of .site-nav but
   must NOT inherit this menu-item styling (display:block sizing collided
   with .pill-group's own layout, and the aria-current color rule below
   painted the active pill's text the same navy as its own background,
   making it invisible — a real bug caught in QA screenshots). */
.site-nav > ul a {
    position: relative;
    display: block;
    min-height: 44px;
    line-height: 44px;
    text-decoration: none;
    color: var(--color-text);
    font-weight: 600;
    border-bottom: 2px solid transparent;
    transition: color 0.15s ease, border-bottom-color 0.15s ease;
}

    /* Hover underline draws left-to-right (scaleX), not a plain color swap —
       an ::after so it's independent of the always-on border-bottom the
       active-page state below uses; the two never coexist on one link
       (the active link's own hover state is excluded further down). */
    .site-nav > ul a::after {
        content: "";
        position: absolute;
        left: 0;
        bottom: -2px;
        width: 100%;
        height: 2px;
        background: var(--color-accent);
        transform: scaleX(0);
        transform-origin: left;
        transition: transform 0.2s ease;
    }

    @media (hover: hover) {
        .site-nav > ul a:hover {
            /* Darker step, not the base accent (2026-07-25) — matches the
               rest of the site committing fully on hover rather than a
               subtle tint shift; see tokens.css's --color-accent-dark. */
            color: var(--color-accent-dark);
        }

        .site-nav > ul a:not([aria-current="page"]):hover::after {
            transform: scaleX(1);
        }
    }

    /* The active page already has its own permanent border-bottom below —
       suppress the hover-draw underline there to avoid a doubled line. */
    .site-nav > ul a[aria-current="page"]::after {
        display: none;
    }

    @media (prefers-reduced-motion: reduce) {
        .site-nav > ul a::after {
            transition: none;
        }
    }

    /* Plain navy underline for the current-page marker — matches the
       reference's own nav-active treatment exactly (measured: 2px solid
       #2c5580), not a second accent hue. */
    .site-nav > ul a[aria-current="page"] {
        font-weight: 700;
        color: var(--color-accent);
        border-bottom-color: var(--color-accent);
    }

/* Language switcher: reuses .pill-group (tokens.css) — same segmented
   two-option control as the Projects category filter, just two plain
   links, no <select>/JS needed. */
.site-nav__lang-wrap {
    margin-top: 0.75rem;
}

/* Minimal, light footer — logo + copyright on the page background with a
   single hairline divider, matching the reference exactly. Supersedes an
   earlier dark navy band with its own grid texture; the sticky-footer
   flex mechanism below (flex: 0 0 auto, as the last child of body's
   flex column in tokens.css) is unchanged and still fixes the original
   reported bug where the footer floated mid-page on short-content pages. */
.site-footer {
    flex: 0 0 auto;
    margin-top: var(--space-section);
    padding: 1.5rem 1.25rem;
    border-top: 1px solid var(--color-divider);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

    .site-footer svg {
        height: 32px;
        width: auto;
        display: block;
    }

.site-footer__copyright {
    margin: 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Desktop: hide the toggle and force the nav visible as a horizontal row,
   regardless of the <details> open/closed attribute state.

   .site-nav-disclosure > .site-nav (not plain .site-nav) is required here,
   not stylistic: browsers ship a UA-stylesheet rule
   "details:not([open]) > *:not(summary) { display: none; }" at specificity
   (0,1,2), and since the <details> never gains an [open] attribute (no JS
   sets it — it's meant to stay closed on mobile until tapped), that native
   rule always applies. A plain ".site-nav { display: flex }" is only
   (0,1,0) and LOSES that specificity battle even inside this @media block,
   so the nav silently stayed display:none at every viewport width — a real
   bug (no navbar ever visible, desktop included) caught by direct visual
   testing, not just a lint/build check. The extra ancestor class here
   raises this rule to (0,2,0), which wins. */
@media (min-width: 768px) {
    .site-nav-disclosure > summary {
        display: none;
    }

    /* .site-nav must itself be the flex row — ul and .site-nav__lang-wrap
       are SIBLING children of it, not nested. Without this, each sits as
       its own block box starting at the nav's left edge, so the dropdown
       renders on its own line under the first nav link instead of beside
       the last one (a real bug shipped and caught by manual QA). */
    .site-nav-disclosure > .site-nav {
        display: flex;
        align-items: center;
        /* Undo the mobile dropdown-panel positioning above — desktop wants
           a plain inline row beside the logo, not an overlay. */
        position: static;
        background: none;
        border-top: none;
        box-shadow: none;
        padding: 0;
    }

    .site-nav ul {
        flex-direction: row;
        align-items: center;
        gap: 1.5rem;
        margin: 0;
    }

    .site-nav__lang-wrap {
        margin-top: 0;
        margin-inline-start: 1.5rem;
    }
}
