/* ============================================================
   CARECOM® Blazor reimplementation — global stylesheet.

   Everything below is genuinely cross-cutting: design tokens,
   base typography, layout primitives used by multiple pages, and
   the few utility classes (.container, .jumbotron, .bullet-list,
   .signature) that appear all over the site.

   Component- and page-specific styles live in scoped *.razor.css
   files next to each .razor — see e.g. SiteFooter.razor.css,
   Home.razor.css. The compiler rewrites those rules with a unique
   [b-xxxxx] scope-id attribute so they never leak globally.

   --- Responsive breakpoints (project convention) -------------
   Use ONLY these two values site-wide so consistent layout shifts
   happen at the same widths everywhere. Earlier the codebase had
   seven different breakpoints scattered across scoped CSS (520,
   560, 600, 640, 720, 980, 1024) — all of those have been folded
   into the two canonical values:

     640px  — mobile-tablet boundary
              (single-column collapses, smaller font, simpler nav)
     980px  — tablet-desktop boundary
              (sidebar drops out, full-width layout, hero rearranges)

   CSS custom properties don't reach into @media queries, so the
   values must be repeated literally. Search-replace if they ever
   need to move.
   ============================================================ */

:root {
    --bg: #ffffff;
    --bg-muted: #f4f6f8;
    --bg-quote: #1d242b;
    --fg: #1d242b;
    --fg-soft: #4a5560;
    --fg-muted: #7a8590;
    --accent: #1f6f8b;
    --accent-dark: #134453;
    --accent-soft: #e3eef3;
    --border: #e2e6ea;
    /* Semantic status colours — used by the events feature, forms and any
       success/warning/error surface. Each has a strong tone (text/border/
       fill) and a soft tint (subtle background); warning additionally has a
       darker -fg because the amber strong tone is too light for body text. */
    --success: #2d7a4f;
    --success-soft: #e6f4ec;
    --warning: #b08000;
    --warning-fg: #6b4d00;
    --warning-soft: #fff4e0;
    --danger: #a04040;
    --danger-soft: #faecec;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.04), 0 1px 3px rgba(0,0,0,.06);
    --shadow-md: 0 4px 12px rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.08);
    --radius: 4px;
    --radius-lg: 8px;
    --content-w: 1100px;
    --font-sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-serif: Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }

html, body {
    margin: 0; padding: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

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

/* ----- Keyboard focus ring -------------------------------------------------
   One consistent focus indicator for every interactive element. :focus-visible
   only matches keyboard focus, so mouse users never see it. Elements with
   tabindex="-1" are deliberately excluded: they are script-only focus targets
   (notably the H1, which FocusOnNavigate focuses after every route change for
   screen readers) and must NOT flash a ring on navigation. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ----- External link marker (mirrors carecom.de's .externalLink::after) -----
   Any anchor that opens in a new tab gets a small "external" glyph after it.
   The marker is suppressed for:
   - anchors that wrap an image (logos, icons),
   - anchors that explicitly opt out via class="no-extlink".
   Dark-surface overrides (footer, cookie banner) live in those components'
   own scoped CSS files. */
a[target="_blank"]:not(.no-extlink):not(:has(img))::after {
    content: "\2197"; /* U+2197 NORTH EAST ARROW */
    font-size: .85em;
    color: var(--fg-muted);
    margin-left: .15em;
    display: inline-block;
    transform: translateY(-.05em);
    text-decoration: none;
}
a[target="_blank"]:not(.no-extlink):not(:has(img)):hover::after {
    color: var(--accent);
}

/* ----- Animated underline for in-flow prose links --------------------------
   On hover an accent underline wipes in from the left instead of the hard
   default underline. Scoped to the article body (.layout-grid__main) of every
   SitePage — header, footer and sidebar sit outside it and stay unaffected.
   Headings links, image links and the icon-bearing shop-link are excluded;
   they are not running text. */
.layout-grid__main a {
    background-image: linear-gradient(currentColor, currentColor);
    background-position: 0 100%;
    background-repeat: no-repeat;
    background-size: 0% 1.5px;
    transition: background-size .25s ease;
}
.layout-grid__main a:hover {
    text-decoration: none;
    background-size: 100% 1.5px;
}
.layout-grid__main :is(h1, h2, h3, h4) a,
.layout-grid__main a.shop-link,
.layout-grid__main a.card,
.layout-grid__main a.blog-post-nav__link,
.layout-grid__main a:has(img) {
    background-image: none;
}
@media (prefers-reduced-motion: reduce) {
    .layout-grid__main a { transition: none; }
}

h1, h2, h3, h4 { color: var(--fg); line-height: 1.25; }
h1 { font-size: 2.4rem; margin: 0 0 1rem; font-weight: 300; }

/* FocusOnNavigate (Routes.razor) sets programmatic focus on the H1 after
   every route change for screen-reader friendliness — it also adds
   tabindex="-1", which takes the H1 out of the normal Tab order. Since
   the H1 is therefore never reachable by keyboard anyway, we can safely
   suppress the default focus ring across the board. */
h1:focus { outline: none; }
h2 { font-size: 1.6rem; margin: 1.4rem 0 .8rem; font-weight: 400; }
h3 { font-size: 1.2rem; margin: 1rem 0 .6rem; font-weight: 600; }
h4 { font-size: .95rem; margin: 0 0 .4rem; font-weight: 600; color: var(--fg-soft); letter-spacing: .02em; }

p { margin: 0 0 1rem; }
img { max-width: 100%; height: auto; display: block; }
code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 0.95em; }

.container {
    width: 100%;
    max-width: var(--content-w);
    margin: 0 auto;
    padding: 0 1.5rem;
}
.container--carousel { padding-top: 1.5rem; }

.muted { color: var(--fg-muted); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ============================================================
   Page layout primitives — shared by SitePage, BlogEntry, NotFound
   ============================================================ */
.page             { display: flex; flex-direction: column; min-height: 100vh; }
.page__main       { flex: 1; }
.main-layout      { padding-top: 1.5rem; padding-bottom: 3rem; }

.layout-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 270px;
    gap: 2.5rem;
}
.layout-grid__main { min-width: 0; }

/* ============================================================
   Cross-page content patterns
   ============================================================ */
.jumbotron {
    background: var(--bg-muted);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    padding: 1.2rem 1.4rem;
    margin: 1.2rem 0 1.6rem;
}
.jumbotron p { margin: 0; font-size: 1.05rem; color: var(--fg-soft); }
.jumbotron p + p { margin-top: .8rem; }

/* ------------ Card -----------------------------------------------------
   The shared surface for content cards — blog teasers, partner cards, the
   events list, the intern dashboard tiles. Padding is deliberately NOT set
   here (each use sets its own), so .card only owns the surface look.
   `.card--hover` is the opt-in lift treatment for navigable cards (links or
   otherwise clickable tiles); a static panel uses `.card` on its own.
   Adopt with class="card <local-class>" (add "card--hover" when navigable). */
.card {
    background: var(--bg-muted);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.card--hover {
    transition: border-color .15s ease, box-shadow .2s ease, transform .2s ease;
}
.card--hover:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-sm);
    transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
    .card--hover:hover { transform: none; }
}

.bullet-list { list-style: none; padding: 0; margin: .5rem 0 1rem; }
.bullet-list li { padding: .35rem 0 .35rem 1.4rem; position: relative; }
.bullet-list li::before { content: "›"; position: absolute; left: 0; color: var(--accent); font-weight: 700; }

/* Category chip — small uppercase kicker used on blog teasers (above the
   title) and on the blog-post hero (between breadcrumbs and headline).
   Generic primitive so the same class works across scoped CSS boundaries
   (BlogTeaser vs BlogEntry don't share a [b-xxx] attribute). Per-category
   modifier swaps the palette so the three sections — consulting (brand
   accent), distribution (warm cream), photography (warm grey) — read at
   a glance when scanning a long list. */
.category-chip {
    display: inline-block;
    padding: .15rem .55rem;
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    border-radius: 3px;
    background: var(--accent-soft);
    color: var(--accent-dark);
}
.category-chip--distribution { background: #fdf1e3; color: #8a4d10; }
.category-chip--photography  { background: #efeae6; color: #4a3f37; }

/* Clickable variant — when the chip is an <a>, it links to the per-category
   blog sub-page (/<lang>/{consulting|distribution|photography}/blog). Override
   the global link reset so the chip keeps its own colour palette; the hover
   darkens the background subtly to signal "this is interactive" without
   adding an underline that would clash with the pill shape. */
a.category-chip          { text-decoration: none; transition: filter .15s ease, box-shadow .15s ease; }
a.category-chip:hover,
a.category-chip:focus-visible {
    filter: brightness(.92);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .08);
    text-decoration: none;
    outline: none;
}

.signature { font-family: var(--font-serif); font-style: italic; font-weight: 400; font-size: 1.4rem; color: var(--fg); margin: 1rem 0; }

/* ------------ Form field ----------------------------------------------
   Shared field wrapper: a block label with a small caption <span> stacked
   above a full-width control. Declared globally (not scoped) on purpose, so
   the rules also reach the <input>/<textarea> that Blazor's <InputText> /
   <InputTextArea> / <InputDate> render — those sit outside component scope
   and would otherwise each need ::deep in the form's own CSS. */
.form-field { display: block; margin-bottom: 1rem; }
.form-field > span {
    display: block;
    font-size: .85rem;
    color: var(--fg-soft);
    margin-bottom: .25rem;
}
.form-field input,
.form-field textarea,
.form-field select {
    width: 100%;
    padding: .55rem .7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    color: var(--fg);
    background: var(--bg);
}
.form-field textarea { resize: vertical; min-height: 4rem; }
.form-field :is(input, textarea, select):focus { border-color: var(--accent); }
.form-field :is(input, textarea, select):disabled {
    opacity: .55;
    cursor: not-allowed;
    background: var(--bg-muted);
}
/* Red * after the label of a required field. Add .is-required to the
   wrapping .form-field. The * footnote at the foot of a form should
   explain the marker once (see SiteContent.Contact.RequiredFootnote). */
.form-field.is-required > span::after {
    content: ' *';
    color: var(--danger);
}
/* Per-field inline error rendered by Blazor's <ValidationMessage> when
   class="form-field__error" is passed. Tighter than form-level errors
   because it sits directly under its own input. */
.form-field__error {
    display: block;
    margin-top: .3rem;
    color: var(--danger);
    font-size: .85rem;
}

/* ------------ Site-wide button primitives -----------------------------
   Primary = accent-filled, attention-grabbing (the single CTA per form/
   section). Secondary = transparent, calm (Cancel, Clear, second-thought
   actions). Used by ContactForm and every form in the Events area. Page-
   specific buttons keep their semantic class and compose with .btn-* for
   the visual recipe — e.g. <button class="btn-primary events-create__submit">.
   ====================================================================== */
.btn-primary {
    background: var(--accent);
    color: var(--bg);
    border: none;
    padding: .65rem 1.4rem;
    border-radius: var(--radius);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: background .15s ease, transform .15s ease, box-shadow .15s ease;
}
.btn-primary:hover {
    background: var(--accent-dark);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}
.btn-primary[disabled] {
    opacity: .6;
    cursor: progress;
    transform: none;
    box-shadow: var(--shadow-sm);
}
.btn-secondary {
    background: transparent;
    color: var(--fg-soft);
    border: 1px solid var(--border);
    padding: .65rem 1.2rem;
    border-radius: var(--radius);
    font: inherit;
    font-weight: 500;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn-secondary:hover {
    background: var(--bg-muted);
    color: var(--fg);
    border-color: var(--fg-muted);
}
.btn-secondary[disabled] {
    opacity: .55;
    cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
    .btn-primary { transition: background .15s ease; }
    .btn-primary:hover { transform: none; box-shadow: var(--shadow-sm); }
}

/* ------------ Sidebar child / sibling menu ----------------------------
   The section sub-page list (or cross-link group list) shown at the top of
   the right column. Global — not scoped — so both the default RightSidebar
   and custom asides (e.g. the Contact page's person-card column) render it
   identically. */
.right-sidebar__child-menu {
    list-style: none;
    padding: 0;
    margin: 0 0 1.5rem;
    font-size: .92rem;
    border-top: 1px solid var(--border);
}
.right-sidebar__child-menu li     { border-bottom: 1px solid var(--border); }
.right-sidebar__child-menu li a   { display: block; padding: .4rem 0; }
.right-sidebar__child-menu-header { padding: .4rem 0; font-weight: 600; color: var(--fg); }

/* ------------ Shop-link (Selbstbedienung pointer) -----------
   Inline link decorated with a small shopping-bag icon. Used in
   prose on the Distribution page and as an aside on Home (DE only).
   Plain `inline` (NOT inline-flex) so the anchor sits cleanly on the
   text baseline; the SVG uses vertical-align to drop itself onto the
   same baseline as the surrounding letters. */
.shop-link__icon {
    width: 1em;
    height: 1em;
    vertical-align: -.18em;
    margin-right: .25em;
}

/* ============================================================
   Blazor template error UI (rendered by App.razor, outside any
   component scope, so this rule must stay global).
   ============================================================ */
#blazor-error-ui {
    color-scheme: light only;
    background: #ffeb3b;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0,0,0,0.2);
    display: none;
    left: 0;
    padding: .6rem 1.25rem .7rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: .75rem; top: .5rem; }

/* ============================================================
   Scroll-reveal utility — elements fade + lift in as they scroll
   into view. Progressive enhancement: the hidden start state is
   gated behind the `js` class (set synchronously in App.razor's
   <head>), so without JavaScript every .reveal element stays
   visible. reveal.js adds `is-visible` via IntersectionObserver.
   prefers-reduced-motion disables the motion entirely.
   ============================================================ */
.js .reveal {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity .6s ease, transform .6s ease;
}
.js .reveal.is-visible {
    opacity: 1;
    transform: none;
}
@media (prefers-reduced-motion: reduce) {
    .js .reveal,
    .js .reveal.is-visible {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ============================================================
   Image lightbox — driven by wwwroot/js/img-lightbox.js. The
   <dialog> is appended to <body> so it lives outside every
   component scope, which is why these rules sit in the global
   stylesheet rather than a scoped *.razor.css.
   ============================================================ */
.img-lightbox {
    /* Strip the dialog's default chrome: we draw nothing of our own
       around the image; the backdrop carries all the visual weight. */
    border: none;
    background: transparent;
    padding: 0;
    max-width: 100vw;
    max-height: 100vh;
}
.img-lightbox::backdrop {
    background: rgba(15, 22, 28, .88);
    backdrop-filter: blur(2px);
}
.img-lightbox img {
    display: block;
    max-width: 95vw;
    max-height: 95vh;
    object-fit: contain;
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
/* Close button — position: fixed places it at the viewport corner regardless
   of where the (content-sized) <dialog> box sits, so it's always reachable.
   Inside the top-layer <dialog>, fixed positioning is relative to the
   viewport. Image clicks are intentionally swallowed (see img-lightbox.js),
   so the explicit ✕ doubles as the visual affordance for "how do I close
   this?" alongside ESC and the backdrop. */
.img-lightbox__close {
    position: fixed;
    top: 1rem;
    right: 1.2rem;
    width: 2.4rem;
    height: 2.4rem;
    font-size: 1.8rem;
    line-height: 1;
    color: #fff;
    background: rgba(255, 255, 255, .12);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    transition: background .15s ease;
}
.img-lightbox__close:hover,
.img-lightbox__close:focus-visible {
    background: rgba(255, 255, 255, .25);
    outline: none;
}

/* View-transition tuning — the JS sets `view-transition-name: img-lightbox`
   on the thumbnail before opening and moves it to the dialog's <img> during
   the transition, so the browser pairs the two snapshots and morphs between
   them (crossfade + position/size). Defaults are quick (0.25s, ease); a
   touch longer with ease-in-out makes the morph for a portrait-sized photo
   feel less hurried. The dialog backdrop fades via the root transition so
   the dark backdrop blooms in around the morphing image rather than after.
   No-op in browsers without the API; the JS falls back to a plain open. */
::view-transition-old(img-lightbox),
::view-transition-new(img-lightbox) {
    animation-duration: .42s;
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
}
::view-transition-group(img-lightbox) {
    animation-duration: .42s;
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
}

/* ============================================================
   Responsive — only rules for cross-component / global selectors
   live here. Per-component responsive overrides sit inside each
   component's scoped CSS file.
   ============================================================ */
@media (max-width: 980px) {
    .layout-grid { grid-template-columns: 1fr; }
}
