/* ==========================================================================
   Krith Solution - public website
   --------------------------------------------------------------------------
   Self-contained stylesheet. It deliberately does NOT load the admin theme
   (Sneat/Bootstrap), because that bundle is built for a dashboard and would
   both bloat this page and fight its layout. The admin panel is untouched.

   The accent colour is injected from the existing `theme_color` setting, so
   the site stays consistent with the brand without a second place to edit it.

   Layout rules that keep the promise of "no horizontal overflow":
     - every section is padded via a max-width container, never fixed widths
     - long words/URLs wrap (overflow-wrap on body)
     - grids collapse with auto-fit/minmax rather than fixed column counts
     - html/body carry overflow-x:hidden as a final backstop
   ========================================================================== */

:root {
    /* These four are re-declared inline by the layout from the existing
       theme_color setting, so changing the brand colour in General Settings
       repaints the site. The values here are only the fallback. */
    --brand: #013296;
    --brand-soft: rgba(1, 50, 150, 0.08);
    --brand-strong: #011f5e;
    --brand-lift: #2e5fc4;
    --brand-glow: rgba(1, 50, 150, .28);

    --ink: #0f172a;
    --ink-muted: #55617a;
    --line: #e6eaf2;
    --surface: #ffffff;
    --surface-alt: #f6f8fc;

    --radius: 16px;
    --radius-sm: 10px;
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06), 0 4px 12px rgba(15, 23, 42, .05);
    --shadow-md: 0 10px 30px rgba(15, 23, 42, .10);
    --shadow-lg: 0 24px 60px rgba(15, 23, 42, .14);

    --container: 1160px;
    --header-h: 76px;
}

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

html {
    scroll-behavior: smooth;
    /* Anchor links must not hide their target under the sticky header. */
    scroll-padding-top: calc(var(--header-h) + 12px);
    overflow-x: hidden;
}

body {
    margin: 0;
    overflow-x: hidden;
    background: var(--surface);
    color: var(--ink);
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
    margin: 0 0 .5rem;
    line-height: 1.18;
    letter-spacing: -0.022em;
    font-weight: 700;
    color: var(--ink);
}
h1 { font-size: clamp(2rem, 5vw, 3.4rem); }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.4rem); }
h3 { font-size: clamp(1.1rem, 2vw, 1.3rem); }
p  { margin: 0 0 1rem; color: var(--ink-muted); }

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: 20px;
}

.section { padding: clamp(56px, 8vw, 104px) 0; }
.section--alt { background: var(--surface-alt); }

/* The brand band. Shared with the hero so the page opens and closes its
   argument in the same colour, and so there is one gradient to maintain. */
.hero,
.section--brand {
    background:
        radial-gradient(1000px 520px at 78% -8%, rgba(255, 255, 255, .20), transparent 60%),
        radial-gradient(760px 420px at 8% 108%, rgba(255, 255, 255, .14), transparent 62%),
        linear-gradient(140deg, var(--brand-strong) 0%, var(--brand) 55%, var(--brand-lift) 100%);
}
.section--brand { position: relative; overflow: hidden; color: #fff; }
.section--brand h2, .section--brand h3 { color: #fff; }
.section--brand p { color: rgba(255, 255, 255, .8); }

.section-head { max-width: 680px; margin: 0 auto clamp(32px, 5vw, 56px); text-align: center; }
.section-head p { font-size: 1.03rem; }

.eyebrow {
    display: inline-block;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--brand);
    background: var(--brand-soft);
    padding: .38rem .8rem;
    border-radius: 999px;
    margin-bottom: 1rem;
}
.eyebrow--onbrand {
    color: #fff;
    background: rgba(255, 255, 255, .16);
    border: 1px solid rgba(255, 255, 255, .24);
}

/* ------------------------------------------------------------- focus --
   Keyboard users get a visible ring everywhere, including on the brand
   bands where a dark outline would disappear. Pointer users see nothing
   extra, because this is :focus-visible rather than :focus. */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
    outline: 3px solid var(--brand);
    outline-offset: 3px;
    border-radius: 6px;
}
.hero :focus-visible,
.section--brand :focus-visible,
.site-footer :focus-visible { outline-color: #fff; }

/* -------------------------------------------------------------- buttons -- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .85rem 1.6rem;
    border-radius: 999px;
    border: 1px solid transparent;
    font-weight: 600;
    font-size: .97rem;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease, background .18s ease, color .18s ease;
    text-align: center;
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }

.btn--primary { background: var(--brand); color: #fff; box-shadow: 0 8px 20px var(--brand-glow); }
.btn--primary:hover { background: var(--brand-strong); color: #fff; box-shadow: 0 12px 28px var(--brand-glow); }

.btn--ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .55); }
.btn--ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }

/* A primary button sitting ON the brand colour, where .btn--primary would
   vanish into its own background. */
.btn--light { background: #fff; color: var(--brand); box-shadow: 0 10px 26px rgba(3, 12, 40, .3); }
.btn--light:hover { background: #fff; color: var(--brand-strong); box-shadow: 0 14px 32px rgba(3, 12, 40, .36); }

.btn--outline { background: #fff; color: var(--brand); border-color: var(--line); box-shadow: var(--shadow-sm); }
.btn--outline:hover { border-color: var(--brand); color: var(--brand); }

.btn--block { width: 100%; }

/* --------------------------------------------------------------- header -- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 60;
    height: var(--header-h);
    display: flex;
    align-items: center;
    background: rgba(255, 255, 255, .82);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid transparent;
    transition: border-color .25s ease, box-shadow .25s ease;
}
.site-header.is-stuck { border-bottom-color: var(--line); box-shadow: var(--shadow-sm); }

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

.brand { display: flex; align-items: center; gap: .65rem; font-weight: 700; color: var(--ink); min-width: 0; }
.brand:hover { text-decoration: none; }
.brand img { height: 38px; width: auto; object-fit: contain; }
.brand__name {
    font-size: 1.05rem;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav { margin-left: auto; display: flex; align-items: center; gap: .35rem; }
.nav a {
    padding: .5rem .85rem;
    border-radius: 8px;
    color: var(--ink-muted);
    font-weight: 500;
    font-size: .95rem;
    white-space: nowrap;
}
.nav a:hover { color: var(--brand); background: var(--brand-soft); text-decoration: none; }
.nav .btn { margin-left: .5rem; padding: .6rem 1.15rem; }

/* `.nav a` is more specific than `.btn--primary`, so without this the header
   CTA inherits the muted link grey and ends up as low-contrast grey text on
   a solid brand background. */
.nav a.btn--primary { color: #fff; }
.nav a.btn--primary:hover { color: #fff; background: var(--brand-strong); }

.nav-toggle {
    display: none;
    margin-left: auto;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: 10px;
    width: 44px; height: 44px;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
    display: block; width: 18px; height: 2px; background: var(--ink); border-radius: 2px;
    transition: transform .22s ease, opacity .22s ease;
}
.nav-toggle span { position: relative; }
.nav-toggle span::before { content: ""; position: absolute; top: -6px; }
.nav-toggle span::after  { content: ""; position: absolute; top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

/* Collapses at 1024px rather than 900px: the nav now carries up to five
   section links plus a button, which is more than a 950px window can hold
   without the brand name being squeezed. */
@media (max-width: 1024px) {
    .nav-toggle { display: inline-flex; }
    .nav {
        position: fixed;
        inset: var(--header-h) 0 auto 0;
        flex-direction: column;
        align-items: stretch;
        gap: .15rem;
        background: #fff;
        border-bottom: 1px solid var(--line);
        box-shadow: var(--shadow-md);
        padding: 1rem 20px 1.4rem;
        margin: 0;
        /* Hidden by default; toggled by [data-open]. Uses visibility so the
           links are not focusable while the menu is closed. */
        transform: translateY(-12px);
        opacity: 0;
        visibility: hidden;
        transition: transform .22s ease, opacity .22s ease, visibility .22s;
    }
    .nav[data-open="true"] { transform: translateY(0); opacity: 1; visibility: visible; }
    .nav a { padding: .8rem .6rem; font-size: 1rem; }
    .nav .btn { margin: .5rem 0 0; }
}

/* ----------------------------------------------------------------- hero --
   The banner images this site is built for are finished 16:9 hero designs,
   not backdrops: each already contains its own headline, its own supporting
   sentence and its own drawn buttons. Two consequences drive this whole
   block:

     1. The artwork is presented WHOLE. It is never cropped to a wider ratio,
        never stretched, and never shrunk into a side column - the viewport
        holds the exact 16:9 of the file, so what the designer drew is what a
        visitor sees.

     2. Nothing is floated on top of it unless the CMS record actually has
        copy to show (see the note in home.blade.php). Carousel controls sit
        BELOW the frame for the same reason - an arrow parked over the left
        edge would land on the logo or the headline.

   Sizing is driven by WIDTH, deliberately.

   An earlier version capped the stage against the viewport HEIGHT, to
   guarantee the next section peeked under the fold. That was the wrong
   lever: a real browser window on a 1440x900 laptop only has ~700-740px of
   viewport once the OS bar, tab strip and bookmarks are taken out, and the
   cap then collapsed a 1600x900 poster to ~620px wide - a thumbnail adrift
   in a field of blue. The artwork is the hero, so width wins; the fold is
   looked after by keeping everything AROUND the artwork small instead.
   -------------------------------------------------------------------- */
.hero {
    --hero-ar: 16 / 9;

    position: relative;
    overflow: hidden;
    color: #fff;
    /* Trimmed hard: every pixel spent here is a pixel of blue around the
       banner, and pushes the next section further down. */
    padding: clamp(14px, 1.4vw, 20px) 0 clamp(18px, 2vw, 26px);
}

/* The hero runs wider than the reading container. Body copy wants ~1160px
   for a comfortable measure; a 16:9 banner just wants room. */
.hero .container { max-width: 1240px; }
.hero::after {
    /* Subtle grid texture. Purely decorative and cheap - no image request. */
    content: "";
    position: absolute; inset: 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
    background-size: 56px 56px;
    mask-image: radial-gradient(circle at 50% 0%, #000 10%, transparent 72%);
    -webkit-mask-image: radial-gradient(circle at 50% 0%, #000 10%, transparent 72%);
    pointer-events: none;
}
.hero .container { position: relative; z-index: 2; }

/* Fills the hero container outright. width:100% of a max-width container can
   never overflow, so this is also what keeps the promise of no horizontal
   scrollbar. */
.hero__stage {
    position: relative;
    width: 100%;
    margin-inline: auto;
}

.hero__viewport {
    position: relative;
    aspect-ratio: var(--hero-ar);
    border-radius: clamp(14px, 1.5vw, 22px);
    overflow: hidden;
    background: rgba(255, 255, 255, .07);
    box-shadow: 0 28px 68px rgba(3, 12, 40, .38);
    outline: 1px solid rgba(255, 255, 255, .16);
    outline-offset: -1px;
}

/* Slides are stacked and crossfaded. visibility (not just opacity) keeps an
   off-screen slide's button out of the tab order. */
.hero__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    transition: opacity .7s ease, visibility .7s;
}
.hero__slide.is-active { opacity: 1; visibility: visible; }

.hero__slide--noimage {
    background: linear-gradient(135deg, rgba(255, 255, 255, .12), rgba(255, 255, 255, .03));
}

.hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* Only rendered for a banner that carries its own words - never over
   finished artwork. */
.hero__overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    padding: clamp(20px, 3.4vw, 52px);
    /* Reaches high enough to sit behind the tallest overlay - eyebrow,
       heading, sentence and button - rather than fading out under the top
       of it and leaving the eyebrow on a bright background. */
    background: linear-gradient(to top,
        rgba(4, 12, 36, .92) 0%,
        rgba(4, 12, 36, .74) 26%,
        rgba(4, 12, 36, .36) 52%,
        rgba(4, 12, 36, 0) 78%);
}
.hero__slide--noimage .hero__overlay { background: none; align-items: center; }

.hero__copy { max-width: 52ch; }
.hero__title {
    color: #fff;
    font-size: clamp(1.45rem, 3.3vw, 2.5rem);
    margin-bottom: .5rem;
    text-shadow: 0 2px 18px rgba(4, 12, 36, .45);
}
.hero__overlay p {
    color: rgba(255, 255, 255, .9);
    font-size: clamp(.94rem, 1.35vw, 1.08rem);
    max-width: 46ch;
    margin-bottom: 1rem;
}
.hero__eyebrow {
    display: inline-block;
    font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: #fff;
    background: rgba(255, 255, 255, .18);
    border: 1px solid rgba(255, 255, 255, .26);
    padding: .34rem .75rem; border-radius: 999px; margin-bottom: .9rem;
}

/* ---- carousel controls: below the artwork, never on it ---------------- */
.hero__controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: clamp(10px, 1.1vw, 14px);
}
.hero__nav {
    width: 34px; height: 34px; flex: 0 0 34px;
    border-radius: 50%;
    display: grid; place-items: center;
    padding: 0; cursor: pointer;
    font-size: 22px; line-height: 1; color: #fff;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .3);
    transition: background .2s ease, transform .2s ease, border-color .2s ease;
}
.hero__nav:hover { background: rgba(255, 255, 255, .26); transform: translateY(-1px); }

.hero__dots { display: flex; align-items: center; gap: .5rem; }
.hero__dot {
    position: relative;
    width: 26px; height: 4px; border-radius: 999px; border: 0; padding: 0; cursor: pointer;
    background: rgba(255, 255, 255, .38);
    transition: background .2s ease, width .2s ease;
}
/* A 4px-tall control is impossible to hit on a phone, so the hit area is
   grown well past the painted dot. */
.hero__dot::after { content: ""; position: absolute; inset: -16px -5px; }
.hero__dot.is-active { background: #fff; width: 42px; }

/* ---- rail: the page's one h1, and its one real call to action --------- */
.hero__rail {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: clamp(16px, 2.4vw, 34px);
    margin-top: clamp(12px, 1.4vw, 18px);
    padding-top: clamp(12px, 1.3vw, 16px);
    border-top: 1px solid rgba(255, 255, 255, .18);
}
.hero__statement {
    flex: 1 1 420px;
    margin: 0;
    max-width: 68ch;
    color: #fff;
    font-size: clamp(.98rem, 1.35vw, 1.18rem);
    font-weight: 600;
    line-height: 1.4;
}
.hero__statement-brand {
    display: block;
    margin-bottom: .22rem;
    font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
    color: rgba(255, 255, 255, .66);
}
.hero__statement-text { display: block; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .7rem; }

/* No banners at all: the rail becomes the hero, built from General Settings. */
.hero__rail--solo {
    flex-direction: column;
    justify-content: center;
    text-align: center;
    border-top: 0;
    margin-top: 0;
    padding: clamp(44px, 8vw, 96px) 0;
}
.hero__rail--solo .hero__statement { flex: 0 1 auto; font-size: clamp(1.55rem, 3.6vw, 2.4rem); }
.hero__rail--solo .hero__statement-brand { font-size: .8rem; margin-bottom: .8rem; }
.hero__rail--solo .hero__logo {
    height: 62px; width: auto; margin: 0 auto 1.4rem;
    filter: brightness(0) invert(1);
    opacity: .95;
}

/* ---- phones -----------------------------------------------------------
   Two problems to solve at once.

   The artwork: a 16:9 poster on a 375px screen is 211px tall and its
   headline is unreadable. Narrowing the frame to 4:3 and anchoring it left
   keeps the part that carries the message - the left-hand content block - at
   a legible size, and loses only the outer edge of the photograph.

   The space around it: at desktop spacing the rail and controls added ~360px
   of blue below a 251px image, so the hero read as a small picture on a big
   empty panel. Everything below the frame is tightened, and the phone gets
   one full-width call to action instead of two. */
@media (max-width: 700px) {
    .hero {
        --hero-ar: 4 / 3;
        padding: 12px 0 18px;
    }
    .hero__stage { max-width: 100%; min-width: 0; }
    .hero__img { object-position: left center; }

    .hero__controls { margin-top: 10px; gap: 12px; }
    .hero__nav { width: 32px; height: 32px; flex: 0 0 32px; font-size: 20px; }

    .hero__rail {
        flex-direction: column;
        align-items: stretch;
        text-align: left;
        gap: 14px;
        margin-top: 14px;
        padding-top: 14px;
    }
    /* flex-basis is a HEIGHT once the rail is a column, so the desktop
       `1 1 420px` would reserve 420px of empty blue below the text. */
    .hero__statement { flex: 0 1 auto; font-size: 1rem; line-height: 1.38; }
    .hero__statement-brand { margin-bottom: .18rem; }

    .hero__actions { gap: .55rem; }
    .hero__actions .btn { flex: 1 1 auto; padding: .78rem 1.2rem; }
    /* The secondary link duplicates a nav entry and costs a whole row of
       height on a phone, so only the primary action survives here. */
    .hero__actions .btn--ghost { display: none; }
}

/* ------------------------------------------------------------- services -- */
.grid { display: grid; gap: 22px; }
.grid--services { grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 30px 26px;
    box-shadow: var(--shadow-sm);
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
    position: relative;
    overflow: hidden;
}
.card::before {
    content: "";
    position: absolute; inset: 0 0 auto 0; height: 3px;
    background: linear-gradient(90deg, var(--brand), #4f7ee8);
    transform: scaleX(0); transform-origin: left;
    transition: transform .28s ease;
}
.card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); border-color: transparent; }
.card:hover::before { transform: scaleX(1); }

.card__icon {
    width: 54px; height: 54px; border-radius: 14px;
    display: grid; place-items: center;
    background: var(--brand-soft);
    color: var(--brand);
    font-size: 26px;
    margin-bottom: 1.1rem;
}
.card__icon img { width: 30px; height: 30px; object-fit: contain; }
.card h3 { margin-bottom: .4rem; }
.card p { margin: 0; font-size: .955rem; }

/* ------------------------------------------------------------ products --
   Ready-made software, and it has to LOOK ready-made. Where a service card
   is a small icon tile, a product is a wide two-column panel with a real
   picture of the thing, a badge that names what it is, and its own page to
   go to. The difference is the point: a visitor must be able to tell at a
   glance which of the two they are looking at. */
.products { display: grid; gap: 22px; }

.product {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    align-items: center;
    gap: clamp(20px, 3vw, 40px);
    padding: clamp(20px, 2.4vw, 28px);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.product:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: transparent; }

/* A featured product leads the section: brand-tinted frame, image first. */
.product--featured {
    border-color: transparent;
    box-shadow: var(--shadow-md);
    background:
        linear-gradient(var(--surface), var(--surface)) padding-box,
        linear-gradient(135deg, var(--brand), var(--brand-lift)) border-box;
    border: 1px solid transparent;
}

.product__media {
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    line-height: 0;
}
.product__media img {
    width: 100%;
    /* CONTAIN, not cover. A product image is a screenshot, and cropping a
       screenshot removes information - a toolbar, a total, a column. Uploads
       vary (the current one is 3:2, a screen capture is usually 16:9), so any
       fixed frame would crop one shape or the other. Contain shows every
       upload whole and lets the frame's own surface fill the remainder.
       The frame keeps a fixed ratio so the card does not change height
       depending on which picture was uploaded. */
    aspect-ratio: 16 / 10;
    object-fit: contain;
    transition: transform .4s ease;
}
.product:hover .product__media img { transform: scale(1.03); }

/* No image uploaded: an icon and the product's initials, never a stock
   screenshot of software we did not photograph. */
.product__fallback {
    /* Flex, not grid: a two-row grid stretches its rows to fill the frame and
       leaves the icon and the initials marooned at opposite ends of it. */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    /* Matches the image frame, so the card is the same height whether or not
       a screenshot has been uploaded. */
    aspect-ratio: 16 / 10;
    background: var(--brand-soft);
    color: var(--brand);
}
.product__fallback i { font-size: clamp(44px, 6vw, 64px); line-height: 1; }
.product__fallback span { font-weight: 800; letter-spacing: .12em; font-size: 1rem; }

.product__badge {
    display: inline-block;
    margin-bottom: .8rem;
    padding: .32rem .75rem;
    border-radius: 999px;
    font-size: .72rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--brand);
    background: var(--brand-soft);
    border: 1px solid rgba(0, 0, 0, .04);
}
.product__body h3 { font-size: clamp(1.2rem, 2.2vw, 1.55rem); margin-bottom: .3rem; }
.product__tagline { color: var(--ink); font-weight: 600; margin-bottom: .5rem; font-size: .99rem; }
.product__body p { font-size: .97rem; }
.product__actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.1rem; }

@media (max-width: 820px) {
    .product { grid-template-columns: 1fr; }
    /* Picture first on a phone: it says "software" faster than a heading. */
    .product__media { order: -1; }
    .product__actions .btn { flex: 1 1 auto; }
}
@media (max-width: 420px) {
    .product__actions { flex-direction: column; }
    .product__actions .btn { width: 100%; }
}

/* ------------------------------------------------------- product page --
   A short brand band instead of the homepage's full carousel hero. */
.hero--page { padding: clamp(24px, 3vw, 44px) 0 clamp(34px, 4.5vw, 60px); }

.crumbs {
    display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
    font-size: .85rem;
    color: rgba(255, 255, 255, .7);
    margin-bottom: clamp(16px, 2.4vw, 28px);
}
.crumbs a { color: rgba(255, 255, 255, .82); }
.crumbs a:hover { color: #fff; }
.crumbs [aria-current] { color: #fff; font-weight: 600; }

.product-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: clamp(24px, 4vw, 52px);
    align-items: center;
}
@media (max-width: 880px) { .product-hero { grid-template-columns: 1fr; } }

.product-hero h1 { color: #fff; font-size: clamp(1.8rem, 4vw, 2.9rem); }
.product-hero__tagline {
    color: #fff; font-weight: 600;
    font-size: clamp(1rem, 1.7vw, 1.18rem);
    margin-bottom: .6rem;
}
.product-hero p { color: rgba(255, 255, 255, .88); max-width: 56ch; }

.product-hero__media img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: contain;
    /* A surface behind the letterboxing, so a screenshot that is not exactly
       16:10 sits on a panel rather than on the brand gradient. */
    background: rgba(255, 255, 255, .1);
    border-radius: var(--radius);
    box-shadow: 0 26px 60px rgba(3, 12, 40, .38);
    outline: 1px solid rgba(255, 255, 255, .18);
    outline-offset: -1px;
}
.product-hero__media .product__fallback--lg {
    border-radius: var(--radius);
    background: rgba(255, 255, 255, .12);
    color: #fff;
    outline: 1px solid rgba(255, 255, 255, .2);
    outline-offset: -1px;
}
.product-hero__media .product__fallback--lg i { font-size: clamp(48px, 7vw, 76px); }

.prose { max-width: 74ch; margin-inline: auto; }
.prose p { font-size: 1.02rem; }
.panel--narrow { max-width: 680px; margin-inline: auto; }
.back-link { text-align: center; margin: clamp(24px, 3vw, 34px) 0 0; }

/* --------------------------------------------------------- technologies --
   A calm grid of equal tiles. One accent colour throughout - the brand -
   rather than a dozen vendor colours, so the section reads as one thing and
   does not compete with the hero above it. The icons come from Remix Icon,
   which the page already loads for the CMS service cards, so this section
   adds no request and no dependency. */
.tech-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
}
.tech {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: .1rem;
    padding: 24px 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.tech:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: transparent; }

.tech__icon {
    width: 52px; height: 52px;
    display: grid; place-items: center;
    margin-bottom: .7rem;
    border-radius: 14px;
    background: var(--brand-soft);
    color: var(--brand);
    font-size: 26px;
    transition: background .2s ease, color .2s ease;
}
.tech:hover .tech__icon { background: var(--brand); color: #fff; }

.tech__name { font-weight: 600; font-size: .98rem; line-height: 1.3; color: var(--ink); }
.tech__category {
    font-size: .72rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ink-muted);
}

/* -------------------------------------------------------------- why us --
   Argument on the left, evidence on the right - the composition reads in
   the order the visitor needs it, and the CTA sits with the argument rather
   than being stranded at the bottom of a list. */
.why {
    display: grid;
    grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
    gap: clamp(28px, 4vw, 58px);
    /* Centred rather than top-aligned: the intro is much shorter than the
       card grid beside it, and pinning it to the top strands it against a
       tall empty column. */
    align-items: center;
}
@media (max-width: 940px) { .why { grid-template-columns: 1fr; } }

.why__intro p { font-size: 1.03rem; max-width: 46ch; }
.why__intro .btn { margin-top: .5rem; }

.why__grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(226px, 1fr));
    gap: 16px;
}
.why__card {
    padding: 24px 22px;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .16);
    transition: transform .2s ease, background .2s ease, border-color .2s ease;
}
.why__card:hover {
    transform: translateY(-4px);
    background: rgba(255, 255, 255, .14);
    border-color: rgba(255, 255, 255, .3);
}
.why__icon {
    width: 44px; height: 44px;
    display: grid; place-items: center;
    margin-bottom: .85rem;
    border-radius: 12px;
    background: rgba(255, 255, 255, .15);
    color: #fff;
    font-size: 22px;
}
.why__card h3 { font-size: 1.02rem; margin-bottom: .3rem; }
.why__card p { font-size: .93rem; margin: 0; color: rgba(255, 255, 255, .76); }

/* ---------------------------------------------------------------- about -- */
.about {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(28px, 5vw, 64px);
    align-items: center;
}
.about--noimage { grid-template-columns: 1fr; max-width: 780px; margin-inline: auto; text-align: center; }
@media (max-width: 880px) { .about { grid-template-columns: 1fr; } }

.about__media img {
    width: 100%;
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    aspect-ratio: 4 / 3;
    object-fit: cover;
}
.about__body p { font-size: 1.02rem; }

.stats { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 1.8rem; }
.stat {
    flex: 1 1 150px;
    min-width: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 18px 16px;
    box-shadow: var(--shadow-sm);
}
.stat__value { font-size: 1.7rem; font-weight: 800; color: var(--brand); line-height: 1.1; }
.stat__label { font-size: .85rem; color: var(--ink-muted); }

/* -------------------------------------------------------------- clients -- */
/* Tracks have a MAXIMUM as well as a minimum, and the row is centred.
   With `1fr` a single public client stretched into one 1120px-wide box with
   a small logo marooned in the middle of it; capped tracks keep one client
   looking like one tile, and a wall of them still fills the row. */
.clients {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 216px));
    justify-content: center;
    gap: 18px;
}
.client {
    display: flex; align-items: center; justify-content: center; gap: .7rem;
    min-height: 104px; padding: 20px 18px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    text-align: center;
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.client:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: transparent; text-decoration: none; }
.client img { max-height: 64px; width: auto; object-fit: contain; }
.client__name { font-weight: 600; color: var(--ink); font-size: .96rem; line-height: 1.35; }

/* Initials badge when a public client has no logo uploaded. */
.client__initials {
    width: 46px; height: 46px; flex: 0 0 46px;
    border-radius: 12px;
    display: grid; place-items: center;
    background: var(--brand-soft); color: var(--brand);
    font-weight: 700; font-size: 1rem;
}

/* -------------------------------------------------------------- contact -- */
.contact { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(26px, 4vw, 48px); align-items: start; }
@media (max-width: 940px) { .contact { grid-template-columns: 1fr; } }

.panel {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: clamp(24px, 3vw, 34px);
    box-shadow: var(--shadow-sm);
}

.field { margin-bottom: 1rem; }
.field label { display: block; font-size: .88rem; font-weight: 600; margin-bottom: .35rem; color: var(--ink); }
.field input, .field textarea {
    width: 100%;
    padding: .8rem .95rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font: inherit;
    color: var(--ink);
    background: #fff;
    transition: border-color .18s ease, box-shadow .18s ease;
}
.field input:focus, .field textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 4px var(--brand-soft);
}
.field textarea { resize: vertical; min-height: 128px; }
.field .err { display: block; margin-top: .3rem; font-size: .83rem; color: #c0263a; }
.field--hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 560px) { .two-up { grid-template-columns: 1fr; } }

.alert { padding: .95rem 1.1rem; border-radius: var(--radius-sm); margin-bottom: 1.1rem; font-size: .94rem; }
.alert--ok  { background: #e8f7ee; color: #17603a; border: 1px solid #bfe6cf; }
.alert--err { background: #fdecee; color: #8c1c2b; border: 1px solid #f5c6cd; }

.contact-list { list-style: none; margin: 0 0 1.4rem; padding: 0; display: grid; gap: 1rem; }
.contact-list li { display: flex; gap: .85rem; align-items: flex-start; }
.contact-list .ico {
    width: 42px; height: 42px; flex: 0 0 42px; border-radius: 12px;
    display: grid; place-items: center;
    background: var(--brand-soft); color: var(--brand); font-size: 20px;
}
.contact-list .lbl { font-size: .78rem; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-muted); font-weight: 700; }
.contact-list .val { color: var(--ink); font-weight: 500; min-width: 0; overflow-wrap: anywhere; }
.contact-list a.val:hover { color: var(--brand); }

.map {
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
    line-height: 0;
}
.map iframe { width: 100%; height: 300px; border: 0; display: block; }

/* --------------------------------------------------------------- footer -- */
.site-footer { background: #0b1220; color: rgba(255, 255, 255, .74); padding: clamp(44px, 6vw, 68px) 0 0; }
.site-footer h4 { color: #fff; font-size: .95rem; margin-bottom: .9rem; letter-spacing: .01em; }
.site-footer a { color: rgba(255, 255, 255, .74); }
.site-footer a:hover { color: #fff; }

.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1.3fr; gap: clamp(24px, 4vw, 52px); }
@media (max-width: 820px) { .footer-grid { grid-template-columns: 1fr; } }

.footer-brand img { height: 40px; width: auto; margin-bottom: 1rem; filter: brightness(0) invert(1); opacity: .92; }
.footer-brand p { color: rgba(255, 255, 255, .62); font-size: .93rem; }

.footer-links { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; font-size: .94rem; }

.socials { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
.socials a {
    width: 40px; height: 40px; border-radius: 11px;
    display: grid; place-items: center; font-size: 19px;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .12);
    transition: background .2s ease, transform .2s ease;
}
.socials a:hover { background: var(--brand); transform: translateY(-2px); text-decoration: none; }

.footer-bottom {
    margin-top: clamp(32px, 5vw, 52px);
    border-top: 1px solid rgba(255, 255, 255, .1);
    padding: 1.2rem 0;
    display: flex; flex-wrap: wrap; gap: .5rem 1.2rem;
    justify-content: space-between; align-items: center;
    font-size: .875rem;
}

/* ------------------------------------------------------------ animation -- */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s ease, transform .6s ease; }
.reveal.is-visible { opacity: 1; transform: none; }

/* Anyone who has asked their OS for less motion gets none of it. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
    .reveal { opacity: 1; transform: none; }
}
