/* ===== Reset & Base ===== */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --color-bg: #fafafa;
    --color-surface: #ffffff;
    --color-text: #111111;
    --color-text-secondary: #555555;
    --color-text-muted: #888888;
    --color-primary: #111111;
    --color-primary-hover: #333333;
    --color-accent: #2563eb;
    /* The logo mark. Fixed in both themes - it is the brand, not a UI accent.
       Same value as OhBrandColor in Studio's Generic.xaml. */
    --color-brand: #2563eb;
    --color-accent-hover: #1d4ed8;
    --color-border: #e5e5e5;
    --color-border-light: #f0f0f0;
    --color-success: #16a34a;
    --color-error: #dc2626;
    --radius: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
    --shadow-md: 0 4px 12px rgba(0,0,0,0.06);
    --shadow-lg: 0 8px 30px rgba(0,0,0,0.08);
    --shadow-xl: 0 20px 60px rgba(0,0,0,0.1);
}

/* ===== Dark theme =====
   A script in header.php resolves the OS setting (or the visitor's saved choice) into
   data-theme="light|dark" on <html> before the page paints, so there is no flash and the CSS only
   needs one condition. Colours are OpenHub Studio's palette (Styles/Generic.xaml), so the site and
   the app look like the same product. */

:root[data-theme="dark"] {
    --color-bg: #0C1016;              /* OhBackground */
    --color-surface: #141A22;         /* OhSurface */
    --color-surface-raised: #1A2230;  /* OhSurfaceElevated */
    --color-text: #E8EDF3;            /* OhPrimaryText */
    --color-text-secondary: #B6C2D1;  /* OhSecondaryText */
    --color-text-muted: #8B98A8;      /* OhMutedText */
    --color-primary: #E8EDF3;         /* inverted: light button, dark label */
    --color-primary-hover: #FFFFFF;
    --color-accent: #5090D3;          /* OhAccent */
    --color-accent-hover: #6BA3DD;
    --color-border: #243040;          /* OhBorder */
    --color-border-light: #1A2230;
    --color-success: #6CCB5F;         /* OhSuccess */
    --color-error: #FF6B6B;           /* OhDanger */
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
    --shadow-md: 0 4px 12px rgba(0,0,0,0.45);
    --shadow-lg: 0 8px 30px rgba(0,0,0,0.5);
    --shadow-xl: 0 20px 60px rgba(0,0,0,0.6);
}

/* Anything sitting on --color-primary needs a dark label now that it is a light surface */
[data-theme="dark"] .btn-primary,
[data-theme="dark"] .lang-split-btn.active,
[data-theme="dark"] .lang-split-btn.active:hover,
[data-theme="dark"] .popular-badge,
[data-theme="dark"] .type-btn.active {
    color: var(--color-bg);
}

/* The accent stays a blue fill, so its label stays light */
[data-theme="dark"] .btn-accent {
    color: #FFFFFF;
}

[data-theme="dark"] .navbar {
    background: rgba(12, 16, 22, 0.85);
}

/* Mock UI panels that hardcoded near-white greys */
[data-theme="dark"] .mock-titlebar,
[data-theme="dark"] .mock-capture-bar,
[data-theme="dark"] .mock-timeline {
    background: var(--color-surface-raised);
}

[data-theme="dark"] .mock-inspector {
    background: var(--color-surface);
}

[data-theme="dark"] .badge {
    background: rgba(80, 144, 211, 0.14);
}

[data-theme="dark"] .badge-inactive {
    color: #FAA825;                    /* OhWarning */
    background: rgba(250, 168, 37, 0.14);
}

/* Screenshots and demo iframes are usually light - dim them slightly so they do not glare */
[data-theme="dark"] .media-item img {
    filter: brightness(0.92);
}

/* Open mobile menu panel - same hardcoded light fill as the navbar */
[data-theme="dark"] .nav-links {
    background: rgba(12, 16, 22, 0.95);
}


html {
    color-scheme: light dark;
    font-family: var(--font);
    font-size: 16px;
    color: var(--color-text);
    background: var(--color-bg);
    scroll-behavior: smooth;
    scrollbar-gutter: stable both-edges;
    -webkit-font-smoothing: antialiased;
}

body {
    line-height: 1.6;
}

a {
    text-decoration: none;
    color: inherit;
    transition: color 0.2s;
}

ul {
    list-style: none;
}

img {
    max-width: 100%;
    height: auto;
}

.container {
    max-width: 1120px;
    margin: 0 auto;
    padding: 0 24px;
}

/* ===== Navbar ===== */
.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: rgba(250, 250, 250, 0.85);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--color-border-light);
}

.navbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 64px;
}

.logo {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    display: flex;
    align-items: center;
    gap: 6px;
}

.logo-icon {
    display: inline-grid;
    grid-template-columns: repeat(2, 10px);
    gap: 3px;
    transform: rotate(45deg);
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    vertical-align: middle;
    margin-right: 4px;
}

.logo-icon span {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: var(--color-brand);
    transition: border-radius 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.logo:hover .logo-icon {
    transform: rotate(0deg);
}

/* Logo idle animations handled by JS */

.nav-links {
    display: flex;
    align-items: center;
    gap: 28px;
    font-size: 0.9rem;
    font-weight: 450;
    color: var(--color-text-secondary);
}

.nav-links a:hover {
    color: var(--color-text);
}

.nav-links > a.active {
    color: var(--color-text);
    font-weight: 600;
}

/* Mobile menu button */
.mobile-menu-btn {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
}

.mobile-menu-btn span {
    width: 22px;
    height: 2px;
    background: var(--color-text);
    border-radius: 2px;
    transition: transform 0.3s, opacity 0.3s;
}

.mobile-menu-btn.open span:nth-child(1) {
    transform: rotate(45deg) translate(5px, 5px);
}

.mobile-menu-btn.open span:nth-child(2) {
    opacity: 0;
}

.mobile-menu-btn.open span:nth-child(3) {
    transform: rotate(-45deg) translate(5px, -5px);
}

/* ===== Fade Up Animation ===== */
@keyframes fadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to { opacity: 1; transform: translateY(0); }
}

.product-card-wide,
.price-card,
.coming-soon-card,
.media-item,
.tool-card,
.support-form,
.support-success,
.license-box,
.status-icon {
    animation: fadeUp 0.5s ease both;
}

.price-card:nth-child(2) { animation-delay: 0.08s; }
.price-card:nth-child(3) { animation-delay: 0.16s; }

.shop-hero,
.hero,
.tools-hero {
    animation: fadeUp 0.4s ease both;
}

/* Pinned to the window edge, positioned against .navbar (already fixed, so it is the containing
   block) rather than the centred .navbar-inner. Out of the flow entirely, so the logo, nav links
   and language switch keep exactly the position they have on pages without a picker. */
/* Starts exactly where the 1120px content column ends - just outside its right edge, rather than
   out at the window edge. 560px is half the container width. */
.currency-split {
    position: absolute;
    left: calc(50% + 560px);
    top: 50%;
    transform: translateY(-50%);
}

/* ===== Theme toggle ===== */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    padding: 0;
    background: none;
    border: none;
    border-left: 1px solid var(--color-border);
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.theme-toggle:hover {
    background: var(--color-border-light);
    color: var(--color-text);
}

.theme-toggle svg {
    width: 15px;
    height: 15px;
}

/* Show the icon for the theme you would switch TO, which is the usual convention */
.theme-icon-moon { display: none; }
[data-theme="dark"] .theme-icon-sun { display: none; }
[data-theme="dark"] .theme-icon-moon { display: block; }

/* ===== Language Split Button ===== */
.lang-split {
    display: flex;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.lang-split-btn {
    font-size: 0.8rem;
    font-weight: 500;
    padding: 5px 14px;
    color: var(--color-text-muted);
    transition: all 0.15s;
    border-right: 1px solid var(--color-border);
}

.lang-split-btn:last-child {
    border-right: none;
}

.lang-split-btn.active {
    background: var(--color-primary);
    color: #fff;
}

.lang-split-btn:hover:not(.active) {
    background: var(--color-border-light);
    color: var(--color-text);
}

.lang-split-btn.active:hover {
    color: #fff;
}

/* ===== Buttons ===== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font);
    font-size: 0.875rem;
    font-weight: 500;
    padding: 8px 18px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
}

.btn-primary {
    background: var(--color-primary);
    color: #fff;
    border-color: var(--color-primary);
}

.btn-primary:hover {
    background: var(--color-primary-hover);
}

.btn-accent {
    background: var(--color-accent);
    color: #fff;
    border-color: var(--color-accent);
}

.btn-accent:hover {
    background: var(--color-accent-hover);
}

.btn-outline {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-border);
}

.btn-outline:hover {
    background: var(--color-surface);
    border-color: var(--color-text-muted);
}

.btn-ghost {
    background: transparent;
    color: var(--color-text-secondary);
}

.btn-ghost:hover {
    color: var(--color-text);
}

.btn-lg {
    padding: 12px 28px;
    font-size: 0.95rem;
    border-radius: var(--radius-lg);
}

.btn-block {
    width: 100%;
    text-align: center;
}

/* ===== Badge ===== */
.badge {
    display: inline-block;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--color-accent);
    background: rgba(37, 99, 235, 0.08);
    padding: 5px 14px;
    border-radius: 999px;
    letter-spacing: 0.01em;
}

/* ===== Add-ons ===== */
.addons-section {
    max-width: 720px;
    margin: 0 auto 60px;
}

.addon-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 24px;
}

.addon-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 20px 24px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.addon-info h3 {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 6px;
}

.addon-desc li {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    padding-left: 16px;
    position: relative;
    line-height: 1.7;
}

.addon-desc li::before {
    content: "+";
    position: absolute;
    left: 0;
    color: var(--color-accent);
}

.addon-buy {
    text-align: right;
    flex-shrink: 0;
    min-width: 150px;
}

.addon-price {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 10px;
}

.addon-price span {
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

.addon-price .price-was {
    display: block;
    font-size: 0.8rem;
}

@media (max-width: 640px) {
    .addon-row { flex-direction: column; align-items: stretch; gap: 14px; }
    .addon-buy { text-align: left; }
}

/* ===== System requirements table ===== */
.spec-table-wrap {
    max-width: 720px;
    margin: 0 auto 60px;
}

.spec-title {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 16px;
    text-align: center;
}

.spec-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.spec-table thead th {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    text-align: left;
    padding: 0 16px 8px;
}

.spec-table tbody th {
    width: 28%;
    font-weight: 500;
    color: var(--color-text-secondary);
    text-align: left;
    padding: 11px 16px;
    border-top: 1px solid var(--color-border-light);
}

.spec-table td {
    padding: 11px 16px;
    border-top: 1px solid var(--color-border-light);
}

.spec-dash {
    color: var(--color-text-muted);
}

/* On a phone the label goes above and the two values stay side by side underneath it - stacking
   all three loses the comparison, which is the only reason the table exists. */
@media (max-width: 640px) {
    .spec-table, .spec-table tbody, .spec-table tr, .spec-table tbody th {
        display: block;
        width: auto;
    }
    .spec-table thead { display: none; }

    .spec-table tr {
        border-top: 1px solid var(--color-border-light);
        padding: 10px 0;
    }

    .spec-table tbody th {
        border-top: none;
        padding: 0 0 6px;
        font-weight: 600;
        color: var(--color-text);
    }

    .spec-table td {
        display: inline-block;
        vertical-align: top;
        width: 50%;
        border-top: none;
        padding: 0 12px 0 0;
        font-size: 0.85rem;
    }

    /* Rows with no recommended value span the full width instead of leaving a gap */
    .spec-table td[colspan] {
        width: 100%;
        padding-right: 0;
    }

    .spec-table td::before {
        content: attr(data-label);
        display: block;
        font-size: 0.7rem;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--color-text-muted);
        margin-bottom: 2px;
    }
}

/* ===== Sale price ===== */
.price-was {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    text-decoration: line-through;
    line-height: 1.2;
}

.price-save {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-success);
    margin-top: 2px;
}

/* Test site only - marks products that are inactive on the live site */
.badge-inactive {
    color: #92400e;
    background: rgba(245, 158, 11, 0.15);
    font-weight: 600;
    margin-left: 6px;
}

/* ===== Loading Spinner ===== */
.logo-spinner {
    display: inline-grid;
    grid-template-columns: repeat(2, 10px);
    gap: 3px;
    animation: logo-spin 0.8s steps(4) infinite;
}

.logo-spinner span {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: var(--color-accent);
}

@keyframes logo-spin {
    0%   { transform: rotate(0deg); }
    25%  { transform: rotate(90deg); }
    50%  { transform: rotate(180deg); }
    75%  { transform: rotate(270deg); }
    100% { transform: rotate(360deg); }
}

/* ===== Landing Hero ===== */
.hero {
    padding: 140px 0 60px;
    text-align: center;
}

.hero-content h1 {
    font-size: 3.5rem;
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.1;
    margin-bottom: 20px;
}

.hero-sub {
    font-size: 1.15rem;
    color: var(--color-text-secondary);
    max-width: 520px;
    margin: 0 auto 32px;
    line-height: 1.6;
}

.hero-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-bottom: 60px;
}

.hero-visual { max-width: 900px; margin: 0 auto; }

/* ===== Mock Studio (hero visual) ===== */
.mock-studio {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl);
    overflow: hidden;
    height: 460px;
    text-align: left;
}

.mock-titlebar {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border-light);
    background: #f7f7f8;
}

.mock-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--color-border);
}

.mock-titlebar-name {
    width: 140px;
    height: 10px;
    border-radius: 5px;
    background: var(--color-border);
    margin-left: 10px;
}

.mock-rec {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: #dc2626;
    background: rgba(220, 38, 38, 0.08);
    padding: 3px 10px;
    border-radius: 999px;
}

.mock-rec-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #dc2626;
    animation: rec-blink 1.6s ease-in-out infinite;
}

@keyframes rec-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

.mock-workspace {
    flex: 1;
    display: flex;
    min-height: 0;
}

.mock-canvas {
    flex: 1;
    position: relative;
    margin: 20px;
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, #eef2ff, #e0e7ff 55%, #dbeafe);
    border: 1px solid var(--color-border-light);
    overflow: hidden;
}

.mock-capture {
    position: absolute;
    inset: 14% 20% 14% 12%;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 34px 20px 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.mock-capture-bar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 22px;
    background: #f7f7f8;
    border-bottom: 1px solid var(--color-border-light);
}

.mock-capture-line {
    height: 10px;
    border-radius: 5px;
    background: var(--color-border-light);
}

.mock-capture-line.w-70 { width: 70%; }
.mock-capture-line.w-50 { width: 50%; }
.mock-capture-line.w-60 { width: 60%; }

.mock-cursor {
    position: absolute;
    top: 58%;
    left: 55%;
    width: 22px;
    height: 22px;
    color: var(--color-primary);
    animation: cursor-drift 7s ease-in-out infinite;
}

.mock-cursor svg {
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 2px 4px rgba(0,0,0,0.25));
}

.mock-click-ring {
    position: absolute;
    top: -9px;
    left: -9px;
    width: 40px;
    height: 40px;
    border: 2px solid var(--color-accent);
    border-radius: 50%;
    opacity: 0;
    animation: click-ring 3.5s ease-out infinite;
}

@keyframes cursor-drift {
    0%, 100% { transform: translate(0, 0); }
    30% { transform: translate(-70px, -40px); }
    60% { transform: translate(40px, 20px); }
}

@keyframes click-ring {
    0%, 55% { opacity: 0; transform: scale(0.3); }
    62% { opacity: 0.8; }
    80% { opacity: 0; transform: scale(1.1); }
    100% { opacity: 0; }
}

.mock-inspector {
    width: 190px;
    border-left: 1px solid var(--color-border-light);
    background: #fbfbfc;
    padding: 20px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.mock-inspector-title {
    height: 12px;
    width: 60%;
    border-radius: 6px;
    background: var(--color-border);
    margin-bottom: 8px;
}

.mock-inspector-row {
    height: 26px;
    border-radius: var(--radius);
    background: var(--color-border-light);
}

.mock-inspector-row.short { width: 65%; }

.mock-timeline {
    position: relative;
    border-top: 1px solid var(--color-border-light);
    background: #f7f7f8;
    padding: 14px 20px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.mock-track {
    position: relative;
    height: 22px;
    border-radius: 6px;
    background: var(--color-border-light);
    overflow: hidden;
}

.mock-clip {
    position: absolute;
    top: 2px;
    bottom: 2px;
    border-radius: 5px;
}

.mock-clip.clip-video { background: linear-gradient(180deg, #60a5fa, #3b82f6); }
.mock-clip.clip-voice { background: linear-gradient(180deg, #34d399, #10b981); }
.mock-clip.clip-fx { background: linear-gradient(180deg, #c4b5fd, #a78bfa); }

.mock-playhead {
    position: absolute;
    top: 8px;
    bottom: 10px;
    left: 20px;
    width: 2px;
    border-radius: 1px;
    background: var(--color-primary);
    z-index: 2;
    animation: playhead-sweep 10s linear infinite;
}

.mock-playhead::before {
    content: "";
    position: absolute;
    top: -5px;
    left: -4px;
    width: 10px;
    height: 8px;
    background: var(--color-primary);
    border-radius: 3px 3px 5px 5px;
}

@keyframes playhead-sweep {
    from { left: 20px; }
    to { left: calc(100% - 22px); }
}

/* ===== Features (landing) ===== */
.features {
    padding: 40px 0 20px;
}

.features-included {
    max-width: 760px;
}

.features-included h3 {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 16px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}

.included-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 48px;
}

.included-list li {
    font-size: 0.95rem;
    color: var(--color-text-secondary);
    padding-left: 24px;
    position: relative;
}

.included-list li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: 600;
}

/* ===== CTA Section ===== */
.cta-section { padding: 100px 0; text-align: center; }
.cta-content h2 { font-size: 2.2rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: 12px; }
.cta-content p { font-size: 1.05rem; color: var(--color-text-secondary); margin-bottom: 28px; }

/* ===== Shop Hero ===== */
.shop-hero {
    padding: 120px 0 60px;
    text-align: center;
}

.shop-hero h1 {
    font-size: 3rem;
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.1;
    margin-bottom: 16px;
}

.shop-hero p {
    font-size: 1.15rem;
    color: var(--color-text-secondary);
    max-width: 520px;
    margin: 0 auto;
    line-height: 1.6;
}

/* ===== Product List ===== */
.products-section {
    padding: 40px 0 100px;
}

/* Wide product card */
.product-card-wide {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    padding: 40px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-surface);
    margin-bottom: 24px;
    transition: box-shadow 0.2s, border-color 0.2s;
    cursor: pointer;
    text-decoration: none;
    color: inherit;
}

.product-card-wide:hover {
    box-shadow: var(--shadow-lg);
    border-color: var(--color-text-muted);
}

.product-card-wide-content {
    flex: 1;
}

.product-card-wide-content .badge {
    margin-bottom: 12px;
}

.product-card-wide-content h2 {
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 10px;
}

.product-card-wide-content p {
    font-size: 0.95rem;
    color: var(--color-text-secondary);
    line-height: 1.6;
    margin-bottom: 16px;
    max-width: 560px;
}

.product-card-features {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
}

.product-card-features li {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    padding-left: 18px;
    position: relative;
}

.product-card-features li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: 600;
}

.product-card-wide-action {
    text-align: center;
    flex-shrink: 0;
}

.product-card-wide-price {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 16px;
    color: var(--color-text);
}

.product-card-wide-price span {
    font-weight: 400;
    color: var(--color-text-muted);
}

/* Legacy grid card (kept for future use) */
.products-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}

.product-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-surface);
    overflow: hidden;
    transition: box-shadow 0.2s, border-color 0.2s, transform 0.2s;
}

.product-card:hover {
    box-shadow: var(--shadow-lg);
    border-color: var(--color-text-muted);
    transform: translateY(-2px);
}

.product-card-image {
    height: 200px;
    background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
    display: flex;
    align-items: center;
    justify-content: center;
    border-bottom: 1px solid var(--color-border-light);
}

.product-card-image img {
    max-height: 160px;
    object-fit: contain;
}

.product-card-image .product-icon {
    width: 80px;
    height: 80px;
    display: inline-grid;
    grid-template-columns: repeat(2, 24px);
    gap: 6px;
}

.product-icon span {
    width: 24px;
    height: 24px;
    border-radius: 4px;
    background: var(--color-accent);
    opacity: 0.7;
}

.product-icon span:first-child {
    opacity: 1;
}

.product-card-body {
    padding: 24px;
}

.product-card-body .badge {
    margin-bottom: 12px;
}

.product-card-body h3 {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: 8px;
}

.product-card-body p {
    font-size: 0.9rem;
    color: var(--color-text-secondary);
    line-height: 1.6;
    margin-bottom: 20px;
}

.product-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.product-price {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.product-price .price-period {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

/* ===== Product Detail Page ===== */
.product-detail {
    padding: 120px 0 80px;
}

.product-detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 60px;
    align-items: start;
}

.product-detail-image {
    background: linear-gradient(135deg, #f3f4f6, #e5e7eb);
    border-radius: var(--radius-xl);
    border: 1px solid var(--color-border);
    height: 400px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.product-detail-image .product-icon-lg {
    display: inline-grid;
    grid-template-columns: repeat(2, 40px);
    gap: 10px;
}

.product-icon-lg span {
    width: 40px;
    height: 40px;
    border-radius: 6px;
    background: var(--color-accent);
    opacity: 0.7;
}

.product-icon-lg span:first-child {
    opacity: 1;
}

.product-detail-info h1 {
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: -0.025em;
    margin-bottom: 12px;
}

.product-detail-info .badge {
    margin-bottom: 16px;
}

.product-detail-info .product-description {
    font-size: 1.05rem;
    color: var(--color-text-secondary);
    line-height: 1.7;
    margin-bottom: 32px;
}

.product-detail-price {
    font-size: 2.5rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    margin-bottom: 4px;
}

.product-detail-price .price-period {
    font-size: 1rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

.product-detail-info .price-note {
    font-size: 0.88rem;
    color: var(--color-text-muted);
    margin-bottom: 24px;
}

.product-features {
    margin-bottom: 32px;
}

.product-features h3 {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 16px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}

.product-features ul {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.product-features li {
    font-size: 0.95rem;
    color: var(--color-text-secondary);
    padding-left: 24px;
    position: relative;
}

.product-features li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: 600;
}

.buy-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.buy-form input[type="email"] {
    font-family: var(--font);
    font-size: 0.95rem;
    padding: 12px 16px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    outline: none;
    transition: border-color 0.2s;
}

.buy-form input[type="email"]:focus {
    border-color: var(--color-accent);
}

/* ===== Success / Cancel Pages ===== */
.status-page {
    padding: 160px 0 100px;
    text-align: center;
}

.status-icon {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 24px;
    font-size: 2rem;
}

.status-icon.success {
    background: rgba(22, 163, 74, 0.1);
    color: var(--color-success);
}

.status-icon.error {
    background: rgba(220, 38, 38, 0.1);
    color: var(--color-error);
}

.status-page h1 {
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: -0.025em;
    margin-bottom: 12px;
}

.status-page p {
    font-size: 1.05rem;
    color: var(--color-text-secondary);
    max-width: 480px;
    margin: 0 auto 32px;
    line-height: 1.6;
}

.license-box {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 24px;
    max-width: 500px;
    margin: 0 auto 32px;
    text-align: left;
}

.license-box label {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    display: block;
    margin-bottom: 8px;
}

.license-box code {
    display: block;
    font-size: 1rem;
    font-family: 'SF Mono', 'Consolas', 'Monaco', monospace;
    background: var(--color-bg);
    padding: 12px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border-light);
    word-break: break-all;
    user-select: all;
}

/* ===== Requirements ===== */
.product-requires {
    font-size: 0.88rem;
    color: var(--color-text-muted);
    margin-top: 12px;
}

.product-requires a {
    color: var(--color-accent);
    text-decoration: underline;
    text-decoration-color: rgba(37, 99, 235, 0.3);
    text-underline-offset: 2px;
}

.product-requires a:hover {
    text-decoration-color: var(--color-accent);
}

/* ===== Media Gallery ===== */
.media-gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    max-width: 960px;
    margin: 0 auto 60px;
}

.media-item {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: var(--color-surface);
}

.media-item:only-child,
.media-item.media-demo {
    grid-column: 1 / -1;
}

.media-image img {
    width: 100%;
    height: auto;
    display: block;
}

.media-video-wrapper,
.media-demo-wrapper {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
}

.media-demo-wrapper {
    padding-bottom: 65%;
}

.media-video-wrapper iframe,
.media-demo-wrapper iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: none;
}

.media-caption {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    padding: 12px 16px;
    text-align: center;
    border-top: 1px solid var(--color-border-light);
}

/* ===== Pricing Section ===== */
.pricing-section {
    margin-bottom: 80px;
}

.pricing-title {
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -0.025em;
    text-align: center;
    margin-bottom: 8px;
}

.pricing-subtitle {
    font-size: 1rem;
    color: var(--color-text-secondary);
    text-align: center;
    margin-bottom: 40px;
}

.pricing-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    align-items: start;
}

.price-card {
    position: relative;
    padding: 32px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-bg);
}

.price-card.featured {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-lg);
    background: var(--color-surface);
}

.popular-badge {
    position: absolute;
    top: -11px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--color-primary);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 3px 14px;
    border-radius: 999px;
}

.price-card h3 {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 8px;
}

.price {
    font-size: 2.5rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    margin-bottom: 4px;
}

.price span {
    font-size: 1rem;
    font-weight: 400;
    color: var(--color-text-muted);
}

.price-desc {
    font-size: 0.88rem;
    color: var(--color-text-muted);
    margin-bottom: 20px;
}

.price-desc-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 20px;
}

.price-desc-list li {
    font-size: 0.95rem;
    color: var(--color-text-secondary);
    padding-left: 24px;
    position: relative;
}

.price-desc-list li::before {
    content: "\2713";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: 600;
}

.plan-email-input {
    font-family: var(--font);
    font-size: 0.95rem;
    padding: 10px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    outline: none;
    transition: border-color 0.2s;
    width: 100%;
    margin-bottom: 10px;
}

.plan-email-input:focus {
    border-color: var(--color-accent);
}

/* ===== Billing Toggle ===== */
.billing-toggle {
    display: flex;
    justify-content: center;
    gap: 0;
    margin-bottom: 32px;
    background: var(--color-border-light);
    border-radius: 999px;
    padding: 4px;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
}

.billing-btn {
    font-family: var(--font);
    font-size: 0.875rem;
    font-weight: 500;
    padding: 8px 24px;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: all 0.2s;
}

.billing-btn.active {
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-sm);
}

.billing-btn:hover:not(.active) {
    color: var(--color-text);
}

.price-billed-yearly {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.save-badge {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    color: #16a34a;
    background: rgba(22, 163, 74, 0.1);
    padding: 3px 10px;
    border-radius: 999px;
    margin-bottom: 8px;
}

/* ===== Coming Soon ===== */
.coming-soon-card {
    text-align: center;
    padding: 48px 32px;
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-bg);
}

.coming-soon-card .badge {
    margin-bottom: 16px;
}

.coming-soon-card h3 {
    font-size: 1.3rem;
    font-weight: 600;
    margin-bottom: 10px;
}

.coming-soon-card p {
    font-size: 0.95rem;
    color: var(--color-text-secondary);
    max-width: 440px;
    margin: 0 auto;
    line-height: 1.6;
}

/* ===== Purchase Modal ===== */
.purchase-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    animation: fadeUp 0.3s ease;
}

.purchase-modal {
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    width: 100%;
    max-width: 580px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: var(--shadow-xl);
}

.purchase-modal-header {
    padding: 24px 28px 16px;
    border-bottom: 1px solid var(--color-border-light);
    position: relative;
}

.purchase-modal-header h2 {
    font-size: 1.3rem;
    font-weight: 700;
    margin-bottom: 4px;
}

.purchase-plan-name {
    font-size: 0.9rem;
    color: var(--color-accent);
    font-weight: 500;
}

.purchase-close {
    position: absolute;
    top: 16px;
    right: 20px;
    background: none;
    border: none;
    font-size: 1.5rem;
    color: var(--color-text-muted);
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radius);
}

.purchase-close:hover {
    background: var(--color-border-light);
    color: var(--color-text);
}

.purchase-modal form {
    padding: 20px 28px 28px;
}

.purchase-field {
    margin-bottom: 16px;
}

.purchase-field label {
    display: block;
    font-size: 0.85rem;
    font-weight: 500;
    margin-bottom: 6px;
    color: var(--color-text);
}

.purchase-field input,
.purchase-field select {
    font-family: var(--font);
    font-size: 0.9rem;
    padding: 10px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    width: 100%;
    outline: none;
    transition: border-color 0.2s;
    background: var(--color-surface);
}

.purchase-field input:focus,
.purchase-field select:focus {
    border-color: var(--color-accent);
}

.purchase-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.purchase-type-toggle {
    display: flex;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.type-btn {
    flex: 1;
    padding: 8px;
    border: none;
    background: var(--color-bg);
    font-family: var(--font);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: all 0.15s;
}

.type-btn.active {
    background: var(--color-primary);
    color: #fff;
}

.purchase-consents {
    margin: 20px 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.purchase-checkbox {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    cursor: pointer;
}

.purchase-checkbox input {
    margin-top: 2px;
    accent-color: var(--color-accent);
}

.purchase-checkbox a {
    color: var(--color-accent);
    text-decoration: underline;
}

.purchase-actions {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
}

@media (max-width: 768px) {
    .purchase-row {
        grid-template-columns: 1fr;
    }
    .purchase-modal {
        max-height: 95vh;
    }
}

/* ===== Support Form ===== */
.support-form {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.support-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.support-field label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text);
}

.support-field input,
.support-field select,
.support-field textarea {
    font-family: var(--font);
    font-size: 0.95rem;
    padding: 12px 16px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    outline: none;
    transition: border-color 0.2s;
    background: var(--color-surface);
    color: var(--color-text);
    width: 100%;
}

.support-field input:focus,
.support-field select:focus,
.support-field textarea:focus {
    border-color: var(--color-accent);
}

.support-field textarea {
    resize: vertical;
    min-height: 120px;
}

.support-success {
    text-align: center;
    padding: 40px 0;
}

.support-success h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 8px;
}

.support-success p {
    color: var(--color-text-secondary);
    font-size: 1rem;
}

.support-error {
    background: rgba(220, 38, 38, 0.08);
    color: var(--color-error);
    padding: 12px 16px;
    border-radius: var(--radius);
    font-size: 0.9rem;
    margin-bottom: 16px;
}

/* ===== Footer ===== */
.footer {
    border-top: 1px solid var(--color-border-light);
    padding: 40px 0;
}

.footer-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
}

.footer-brand {
    font-weight: 700;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    gap: 6px;
}

.footer-links {
    display: flex;
    gap: 24px;
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

.footer-links a:hover {
    color: var(--color-text);
}

.footer-copy {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* ===== Responsive ===== */
@media (max-width: 768px) {
    .hero-content h1 {
        font-size: 2.2rem;
    }
    .mock-inspector { display: none; }
    .mock-studio { height: 340px; }
    .mock-capture { inset: 10% 12% 10% 8%; }

    .included-list {
        grid-template-columns: 1fr;
    }
    .shop-hero h1 {
        font-size: 2.2rem;
    }

    .shop-hero p {
        font-size: 1rem;
    }

    .media-gallery {
        grid-template-columns: 1fr;
    }

    .product-card-wide {
        flex-direction: column;
        text-align: center;
        gap: 24px;
        padding: 28px;
    }

    .product-card-wide-content p {
        max-width: none;
    }

    .product-card-features {
        justify-content: center;
    }

    .products-grid,
    .pricing-grid {
        grid-template-columns: 1fr;
    }

    .product-detail-grid {
        grid-template-columns: 1fr;
        gap: 32px;
    }

    .product-detail-image {
        height: 260px;
    }

    .nav-links {
        display: none;
        position: absolute;
        top: 64px;
        left: 0;
        right: 0;
        background: rgba(250, 250, 250, 0.95);
        backdrop-filter: blur(12px);
        flex-direction: column;
        padding: 24px;
        border-bottom: 1px solid var(--color-border-light);
        gap: 16px;
    }

    .nav-links.open {
        display: flex;
    }

    .mobile-menu-btn {
        display: flex;
    }

    .footer-inner {
        flex-direction: column;
        text-align: center;
    }
}

@media (max-width: 1024px) and (min-width: 769px) {
    .products-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ===== Customer portal ===== */
.portal-form { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }

.portal-form label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-secondary);
}

.portal-form input {
    font-family: var(--font);
    font-size: 1rem;
    padding: 12px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    margin-bottom: 8px;
}

.portal-form input:focus {
    outline: none;
    border-color: var(--color-accent);
}

.portal-code-input {
    font-family: Consolas, monospace;
    font-size: 1.6rem;
    letter-spacing: 0.4em;
    text-align: center;
}

.portal-hint {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin-top: 10px;
}

.portal-error {
    font-size: 0.9rem;
    color: var(--color-error);
    background: rgba(220, 38, 38, 0.08);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 16px;
}

.portal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 32px;
}

.portal-license {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 24px;
    margin-bottom: 20px;
}

.portal-license-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
}

.portal-license-head h2 { font-size: 1.15rem; font-weight: 600; }

.portal-key {
    font-family: Consolas, monospace;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-top: 4px;
}

/* Licence state and update window, stacked. Two answers, so two badges - never one. */
.portal-badges {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
    flex-shrink: 0;
}

.portal-window {
    flex-shrink: 0;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--color-success);
    background: rgba(22, 163, 74, 0.1);
    padding: 5px 12px;
    border-radius: 999px;
    white-space: nowrap;
}

.portal-window.lapsed {
    color: #92400e;
    background: rgba(245, 158, 11, 0.15);
}

.portal-versions { width: 100%; border-collapse: collapse; font-size: 0.9rem; }

.portal-versions td {
    padding: 12px 8px;
    border-top: 1px solid var(--color-border-light);
    vertical-align: middle;
}

.portal-versions tr.not-covered td { opacity: 0.55; }

.portal-version-no { font-weight: 600; }

.portal-latest {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-accent);
    margin-left: 8px;
}

.portal-version-date,
.portal-version-size { color: var(--color-text-muted); font-size: 0.85rem; }

.portal-version-action { text-align: right; }

.portal-locked { font-size: 0.8rem; color: var(--color-text-muted); cursor: help; }

.portal-upgrades {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--color-border-light);
}

.portal-upgrades h3 { font-size: 1rem; font-weight: 600; margin-bottom: 4px; }

/* Jump list above the cards, and the tab strip on the help pages. */
.portal-index {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 20px;
}

.portal-index a {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    padding: 6px 14px;
    text-decoration: none;
}

.portal-index a:hover,
.portal-index a.active { color: var(--color-accent); border-color: var(--color-accent); }

/* Question or bug, above the form they both post to. */
.support-kind { margin-bottom: 14px; }

/* One field that reads as a licence key whether or not it is showing one: the dots, the key, the
   eye and the copy button all sit in the same box, so nothing shifts when it opens. The border is
   on the wrapper rather than on the summary, since the copy button has to live outside the
   <details> - inside it, a click on Copy would also toggle the key open. */
.portal-key-field {
    display: inline-flex;
    align-items: stretch;
    margin-top: 8px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    overflow: hidden;
    transition: border-color 0.15s;
}

.portal-key-field:hover { border-color: var(--color-text-muted); }

.portal-key-reveal summary {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    padding: 6px 10px 6px 12px;
    list-style: none;
    transition: background 0.15s;
}

.portal-key-reveal summary::-webkit-details-marker { display: none; }
.portal-key-reveal summary:hover { background: var(--color-surface); }

.portal-key-copy {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    padding: 0;
    border: 0;
    border-left: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
}

.portal-key-copy:hover { color: var(--color-accent); background: var(--color-surface); }
.portal-key-copy svg { width: 15px; height: 15px; }

/* Confirmation lives on the button itself - a tick where the icon was, for a moment. */
.portal-key-copy .icon-copied { display: none; }
.portal-key-copy.copied { color: var(--color-success); }
.portal-key-copy.copied .icon-copy { display: none; }
.portal-key-copy.copied .icon-copied { display: inline; }

.portal-key-reveal .portal-key {
    margin: 0;
    font-size: 0.82rem;
    letter-spacing: 0.02em;
}

/* Dots and key occupy the same grid cell, so the field is always as wide as the wider of the two.
   They are switched with visibility rather than display: a hidden item still takes its space in
   the grid, which is what keeps the box from resizing when the key appears. Both are monospace
   with the same letter-spacing, so the two states line up character for character. */
.portal-key-stack { display: inline-grid; }

.portal-key-stack > .portal-key {
    grid-area: 1 / 1;
    font-family: Consolas, monospace;
    letter-spacing: 0.08em;
    white-space: nowrap;
}

/* Muted while hidden - it is a placeholder, not information. The revealed key gets full contrast. */
.portal-key-masked {
    color: var(--color-text-muted);
    opacity: 0.7;
}

.portal-key-real {
    visibility: hidden;
    color: var(--color-text);
    font-weight: 500;
    user-select: all;
}

.portal-key-eye {
    display: inline-flex;
    align-items: center;
    color: var(--color-text-muted);
    padding: 2px;
}

.portal-key-eye svg { width: 16px; height: 16px; }
.portal-key-eye .icon-eye-off { display: none; }

.portal-key-reveal summary:hover .portal-key-eye { color: var(--color-accent); }

/* Open: the key takes the dots' place and the eye closes. Nothing is left standing above it. */
.portal-key-reveal[open] .portal-key-masked { visibility: hidden; }
.portal-key-reveal[open] .portal-key-real { visibility: visible; }
.portal-key-reveal[open] .icon-eye { display: none; }
.portal-key-reveal[open] .icon-eye-off { display: inline; }

/* The reveal: one wipe across the field. The dots are cleared from the left edge at the same rate
   as the key arrives behind them, so it reads as a single movement rather than two things swapping.
   Both run on the same curve and duration - that is what keeps them locked together. */
@keyframes portal-key-in {
    from { clip-path: inset(0 100% 0 0); }
    to   { clip-path: inset(0 0 0 0); }
}

@keyframes portal-key-out {
    from { clip-path: inset(0 0 0 0); opacity: 0.7; }
    to   { clip-path: inset(0 0 0 100%); opacity: 0; }
}

.portal-key-reveal[open] .portal-key-real {
    animation: portal-key-in 0.45s cubic-bezier(0.5, 0, 0.2, 1) both;
}

.portal-key-reveal[open] .portal-key-masked {
    visibility: visible;
    animation: portal-key-out 0.45s cubic-bezier(0.5, 0, 0.2, 1) both;
}

/* Someone who has turned animation off in their OS gets the key, not the show. */
@media (prefers-reduced-motion: reduce) {
    .portal-key-reveal[open] .portal-key-real,
    .portal-key-reveal[open] .portal-key-masked { animation: none; }
    .portal-key-reveal[open] .portal-key-masked { visibility: hidden; }
}

.portal-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }

/* The one download that matters, given the weight to match. */
.portal-latest-release {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.portal-latest-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.portal-latest-version { font-size: 1.35rem; font-weight: 600; line-height: 1.2; }

.portal-latest-meta {
    display: block;
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--color-text-muted);
    margin-top: 2px;
}

.portal-notes {
    margin: 12px 0 0 18px;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.portal-notes li { margin-bottom: 3px; }

.portal-older { margin-top: 16px; }

.portal-older summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text-muted);
}

.portal-older summary:hover { color: var(--color-accent); }

/* Articles */
.portal-article-item {
    border-bottom: 1px solid var(--color-border-light);
    padding: 14px 0;
}

.portal-article-item summary,
.portal-article-link {
    cursor: pointer;
    font-weight: 500;
    text-decoration: none;
    color: var(--color-text);
}

.portal-article-item summary:hover,
.portal-article-link:hover { color: var(--color-accent); }

.portal-article-link {
    display: block;
    border-bottom: 1px solid var(--color-border-light);
    padding: 14px 0;
}

.portal-article { font-size: 0.93rem; line-height: 1.65; }
.portal-article h2 { font-size: 1.3rem; font-weight: 600; margin-bottom: 14px; }
.portal-article h3 { font-size: 1.05rem; font-weight: 600; margin: 22px 0 8px; }
.portal-article h4 { font-size: 0.95rem; font-weight: 600; margin: 18px 0 6px; }
.portal-article p { margin-bottom: 12px; }
.portal-article ul,
.portal-article ol { margin: 0 0 12px 20px; }
.portal-article li { margin-bottom: 4px; }
.portal-article hr { border: 0; border-top: 1px solid var(--color-border-light); margin: 20px 0; }

.portal-article blockquote {
    border-left: 3px solid var(--color-border);
    padding-left: 14px;
    color: var(--color-text-muted);
    margin-bottom: 12px;
}

.portal-article code {
    font-family: Consolas, monospace;
    font-size: 0.85em;
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: 4px;
    padding: 1px 5px;
}

.portal-article .md-code {
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: 14px 16px;
    overflow-x: auto;
    margin-bottom: 14px;
}

.portal-article .md-code code { background: none; border: 0; padding: 0; }

@media (max-width: 640px) {
    .portal-header,
    .portal-license-head { flex-direction: column; }
    .portal-badges { align-items: flex-start; flex-direction: row; flex-wrap: wrap; }
    .portal-versions td { padding: 8px 4px; }
    .portal-version-size { display: none; }
    .portal-latest-release { flex-direction: column; align-items: stretch; }
    .portal-latest-release .btn { width: 100%; }
}

[data-theme="dark"] .portal-error { background: rgba(255, 107, 107, 0.12); }
[data-theme="dark"] .portal-window { background: rgba(108, 203, 95, 0.12); }
[data-theme="dark"] .portal-window.lapsed { color: #FAA825; background: rgba(250, 168, 37, 0.14); }

.portal-machines {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--color-border-light);
}

.portal-machines h3 { font-size: 1rem; font-weight: 600; margin-bottom: 4px; }

.portal-ok {
    font-size: 0.9rem;
    color: var(--color-success);
    background: rgba(22, 163, 74, 0.08);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 16px;
}

[data-theme="dark"] .portal-ok { background: rgba(108, 203, 95, 0.12); }

.portal-machines-link {
    font-size: 0.85rem;
    color: var(--color-accent);
}

.portal-machines-link:hover { text-decoration: underline; }

/* [Premium] in plan copy becomes a pill */
.feature-tag {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--color-accent);
    background: rgba(37, 99, 235, 0.1);
    padding: 1px 8px;
    border-radius: 999px;
    margin-left: 4px;
    vertical-align: 1px;
}

[data-theme="dark"] .feature-tag { background: rgba(80, 144, 211, 0.16); }

/* ===== Article media: figures, the video player, the YouTube facade ===== */

.md-figure { margin: 0 0 18px; }

.md-figure img {
    display: block;
    width: 100%;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
}

.md-figure figcaption {
    margin-top: 8px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    text-align: center;
}

.portal-article p > img { border-radius: var(--radius); vertical-align: middle; }

/* The player. The <video> has no controls attribute - this bar is the whole interface, so it looks
   the same in every browser instead of inheriting each one's native chrome.

   The bar sits *under* the picture rather than over it: nothing the video shows is ever covered,
   and the controls read as part of the page instead of as an overlay. That is also why they are in
   the site's own colours rather than white-on-black. */
.oh-player {
    margin: 0 0 18px;
    line-height: 0;
    outline: none;
}

.oh-player:focus-visible .oh-player-frame { box-shadow: 0 0 0 3px var(--color-accent); }

.oh-player-frame {
    position: relative;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    overflow: hidden;
    background: #000;
}

.oh-player video { display: block; width: 100%; height: auto; cursor: pointer; }

/* Big centre button, gone once it is playing. */
.oh-player-poster {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border: 0;
    background: rgba(0, 0, 0, 0.22);
    color: #fff;
    cursor: pointer;
    transition: opacity 0.25s;
}

.oh-player-poster svg {
    width: 32px; height: 32px;
    padding: 16px;
    box-sizing: content-box;
    background: rgba(17, 17, 17, 0.72);
    border-radius: 999px;
    backdrop-filter: blur(6px);
    transition: transform 0.2s, background 0.2s;
}

.oh-player-poster:hover svg { transform: scale(1.06); background: var(--color-accent); }
.oh-player.playing .oh-player-poster { opacity: 0; pointer-events: none; }

/* Always visible - it is part of the frame, not something that appears on hover. */
.oh-player-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    line-height: 1;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-top: 0;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.oh-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: color 0.15s, transform 0.15s;
}

.oh-btn:hover { color: var(--color-accent); transform: scale(1.08); }
.oh-btn svg { width: 18px; height: 18px; }

.oh-i-pause, .oh-i-muted { display: none; }
.oh-player.playing .oh-i-play { display: none; }
.oh-player.playing .oh-i-pause { display: inline; }
.oh-player.muted .oh-i-vol { display: none; }
.oh-player.muted .oh-i-muted { display: inline; }

.oh-time {
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;   /* so the bar does not twitch as the seconds tick */
    color: var(--color-text-muted);
    min-width: 34px;
    text-align: center;
}

/* Padded above and below so the pointer target is comfortable while the bar stays thin. */
.oh-track {
    position: relative;
    flex: 1;
    height: 4px;
    margin: 10px 0;
    border-radius: 999px;
    background: var(--color-border);
    cursor: pointer;
    touch-action: none;
}

.oh-track::before {
    content: '';
    position: absolute;
    inset: -10px 0;
}

.oh-buffered, .oh-played {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    border-radius: 999px;
}

.oh-buffered { background: var(--color-border-light); width: 0; }
.oh-played { background: var(--color-accent); width: 0; }

.oh-knob {
    position: absolute;
    top: 50%;
    left: 0;
    width: 11px; height: 11px;
    margin-left: -5.5px;
    border-radius: 50%;
    background: var(--color-accent);
    transform: translateY(-50%) scale(0);
    transition: transform 0.15s;
}

.oh-player:hover .oh-knob { transform: translateY(-50%) scale(1); }

/* Cinema view: the player breaks out of the article column to the full width of the window, and the
   picture keeps its own proportions inside a black frame. The page stays where it is and still
   scrolls - nothing is handed to the browser's fullscreen overlay, which would take this bar with
   it and hand the visitor back whatever chrome their browser ships.

   The breakout is the classic pair: 100vw wide, pulled left by half the difference. calc(50% - 50vw)
   works whatever the container width is, so it needs no knowledge of the 820px column. */
.oh-player.cinema {
    width: 100vw;
    max-width: none;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
}

.oh-player.cinema .oh-player-frame {
    border-radius: 0;
    display: flex;
    justify-content: center;
}

/* Capped so a tall window does not stretch the picture past what fits on screen at once. */
.oh-player.cinema video { width: auto; max-width: 100%; max-height: 78vh; }

.oh-player.cinema .oh-player-bar {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
}

.oh-i-narrow { display: none; }
.oh-player.cinema .oh-i-wide { display: none; }
.oh-player.cinema .oh-i-narrow { display: inline; }

/* YouTube, click to load. Until then this is a thumbnail and a button - no iframe, no cookies. */
.oh-embed {
    position: relative;
    margin: 0 0 18px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: #000;
    aspect-ratio: 16 / 9;
    line-height: 0;
}

.oh-embed img, .oh-embed iframe {
    width: 100%;
    height: 100%;
    border: 0;
    object-fit: cover;
    display: block;
}

.oh-embed-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border: 0;
    background: rgba(0, 0, 0, 0.2);
    color: #fff;
    cursor: pointer;
    transition: background 0.25s;
}

.oh-embed-play svg {
    width: 30px; height: 30px;
    padding: 15px 17px 15px 19px;
    box-sizing: content-box;
    background: rgba(17, 17, 17, 0.75);
    border-radius: 999px;
    transition: transform 0.2s, background 0.2s;
}

.oh-embed-play:hover svg { transform: scale(1.07); background: #e02f2f; }

/* Article search */
.portal-search {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 18px;
    padding: 9px 14px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    transition: border-color 0.15s;
}

.portal-search:focus-within { border-color: var(--color-accent); }
.portal-search svg { width: 16px; height: 16px; color: var(--color-text-muted); flex-shrink: 0; }

.portal-search input[type="search"] {
    flex: 1;
    border: 0;
    outline: none;
    background: transparent;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--color-text);
}

.portal-search input[type="search"]::-webkit-search-cancel-button { display: none; }

.portal-search-clear {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.portal-search-clear:hover { color: var(--color-accent); }

.portal-result-title { display: block; font-weight: 500; }

.portal-result-where {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-top: 3px;
}

.portal-result-excerpt {
    display: block;
    margin-top: 4px;
    font-size: 0.84rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

.portal-result-excerpt mark {
    background: rgba(37, 99, 235, 0.14);
    color: inherit;
    border-radius: 3px;
    padding: 0 2px;
}

[data-theme="dark"] .portal-result-excerpt mark { background: rgba(80, 144, 211, 0.22); }

/* Support form inside the portal */
.support-form-inline { display: flex; flex-direction: column; gap: 14px; }
.support-form-inline label { display: flex; flex-direction: column; gap: 5px; }

.support-form-inline label > span {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.support-form-inline input,
.support-form-inline select,
.support-form-inline textarea {
    font-family: inherit;
    font-size: 0.92rem;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 10px 12px;
    outline: none;
    transition: border-color 0.15s;
}

.support-form-inline input:focus,
.support-form-inline select:focus,
.support-form-inline textarea:focus { border-color: var(--color-accent); }

.support-form-inline textarea { resize: vertical; line-height: 1.6; }
.support-form-inline button { align-self: flex-start; }

/* Numbered lists in an article are steps: the digit sits in a circle beside the text. The numbers
   come from a CSS counter, so the author writes 1. 2. 3. and inserting a step renumbers the rest. */
.portal-article .md-steps,
.article-preview .md-steps {
    counter-reset: step;
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
}

.portal-article .md-steps > li,
.article-preview .md-steps > li {
    counter-increment: step;
    position: relative;
    padding-left: 42px;
    min-height: 28px;
    margin-bottom: 14px;
}

.portal-article .md-steps > li::before,
.article-preview .md-steps > li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: -1px;
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--color-accent);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* A block written inside [brackets] becomes a card - for the thing that is easy to miss. Same
   shape as the release block on the account page, so a card reads as a card everywhere. */
.portal-article .md-card,
.article-preview .md-card {
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
    margin: 0 0 18px;
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--color-text-secondary);
}

/* Support conversations */
.portal-threads {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.portal-thread {
    display: block;
    padding: 14px 18px;
    border-bottom: 1px solid var(--color-border-light);
    text-decoration: none;
    transition: background 0.15s;
}

.portal-thread:last-child { border-bottom: 0; }
.portal-thread:hover { background: var(--color-bg); }
.portal-thread-subject { display: block; font-weight: 500; color: var(--color-text); }

.portal-thread-meta {
    display: block;
    margin-top: 3px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.portal-thread-done {
    display: inline-block;
    margin-left: 6px;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--color-success);
    background: rgba(22, 163, 74, 0.1);
    padding: 1px 8px;
    border-radius: 999px;
}

[data-theme="dark"] .portal-thread-done { background: rgba(108, 203, 95, 0.12); }

/* A message in a conversation. Ours is tinted and sits slightly in, so the two sides read apart
   without needing avatars or names on every line. */
.portal-msg {
    padding: 12px 16px;
    border-radius: var(--radius);
    background: var(--color-bg);
    border-left: 3px solid var(--color-border);
    margin-bottom: 10px;
}

.portal-msg-ours {
    border-left-color: var(--color-accent);
    background: rgba(37, 99, 235, 0.05);
    margin-left: 16px;
}

[data-theme="dark"] .portal-msg-ours { background: rgba(80, 144, 211, 0.09); }

.portal-msg-head {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.portal-msg-body { font-size: 0.9rem; line-height: 1.6; }

/* ===== Pieces of the app's interface, drawn inside a guide =====
   Drawings, not controls - no cursor change, no hover, nothing to click. They exist so a sentence
   can point at the thing the reader is looking for on their own screen. */

.ui-btn,
.ui-select,
.ui-nav,
.ui-seg {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    font-size: 0.82rem;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    margin: 0 2px;
}

.ui-btn {
    padding: 7px 14px;
    border-radius: 6px;
}

.ui-btn-primary {
    background: var(--color-accent);
    color: #fff;
}

.ui-btn-secondary {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-text);
}

/* A pair of options where one is chosen - Smooth | Dynamic. */
.ui-seg {
    padding: 3px;
    gap: 3px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.ui-seg-item {
    padding: 5px 12px;
    border-radius: 6px;
    color: var(--color-text-secondary);
}

.ui-seg-item.active {
    background: var(--color-accent);
    color: #fff;
}

/* Sidebar item: the blue marker down the left edge is what identifies it. */
.ui-nav {
    position: relative;
    padding: 7px 14px 7px 16px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    color: var(--color-text);
}

.ui-nav::before {
    content: '';
    position: absolute;
    left: 5px;
    top: 7px;
    bottom: 7px;
    width: 3px;
    border-radius: 2px;
    background: var(--color-accent);
}

.ui-select {
    gap: 10px;
    padding: 7px 12px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    color: var(--color-text);
}

.ui-select svg { width: 14px; height: 14px; color: var(--color-text-muted); }

/* On their own line they read as an illustration rather than as part of a sentence. */
.portal-article p > .ui-btn:only-child,
.portal-article p > .ui-seg:only-child,
.portal-article p > .ui-nav:only-child,
.portal-article p > .ui-select:only-child { margin: 4px 0; }

/* An unanswered reply waiting to be read. Blue rather than green: it is news, not a result. */
.portal-thread-new {
    display: inline-block;
    margin-right: 6px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #fff;
    background: var(--color-accent);
    padding: 2px 9px;
    border-radius: 999px;
}

/* The thread it belongs to reads as unfinished business. */
.portal-thread:has(.portal-thread-new) .portal-thread-subject { font-weight: 600; }

/* ===== Product landing page (videostudio.no and any other domain in SITE_DOMAINS) =====

   The hero is dark in both themes on purpose. It is a stage: the product is a screen recorder, and
   a screen shows best against something that is not another white page. Everything below it follows
   the visitor's theme as usual. */

.lp-hero {
    position: relative;
    padding: 96px 0 0;
    background: var(--color-bg);
    color: var(--color-text);
    overflow: hidden;
}

/* The glow behind the picture. One soft ellipse, not a gradient across the whole section, so the
   eye lands on the product rather than on the background.

   Weaker in light mode: on a pale page a strong wash reads as a stain, while against the dark theme
   it is what separates the picture from the canvas. */
.lp-hero::before {
    content: '';
    position: absolute;
    top: 12%;
    left: 50%;
    width: min(1100px, 120vw);
    height: 620px;
    transform: translateX(-50%);
    background: radial-gradient(ellipse at center, rgba(37, 99, 235, 0.10), transparent 65%);
    pointer-events: none;
}

[data-theme="dark"] .lp-hero::before {
    background: radial-gradient(ellipse at center, rgba(80, 144, 211, 0.28), transparent 65%);
}

/* The picture keeps its own frame in both themes - a screen recording is dark by nature, and a
   white border round it would fight the content. */
[data-theme="dark"] .lp-frame { border-color: rgba(255, 255, 255, 0.09); }

.lp-hero .container { position: relative; text-align: center; }

.lp-title {
    font-size: clamp(2.6rem, 6vw, 4.4rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.05;
    margin-bottom: 18px;
}

.lp-lead {
    max-width: 620px;
    margin: 0 auto 32px;
    font-size: clamp(1rem, 2vw, 1.2rem);
    line-height: 1.6;
    color: var(--color-text-secondary);
}

.lp-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 64px; }

/* Tilted back, straightening as it rises. --lp-settle runs 0 to 1 as the stage crosses the window;
   with no JavaScript it stays at 1 and the picture simply sits straight. */
.lp-stage {
    --lp-settle: 1;
    perspective: 1600px;
    padding-bottom: 80px;
}

.lp-stage .lp-frame {
    transform: rotateX(calc((1 - var(--lp-settle)) * 9deg)) scale(calc(0.94 + var(--lp-settle) * 0.06));
    transform-origin: 50% 100%;
    will-change: transform;
}

.lp-frame {
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: #000;
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-xl);
    line-height: 0;
}

.lp-frame img,
.lp-frame iframe { display: block; width: 100%; border: 0; }
.lp-frame iframe { aspect-ratio: 16 / 9; height: auto; }

/* ---- sections below the stage ---- */

.lp-section { padding: 88px 0; }

.lp-h2 {
    font-size: clamp(1.6rem, 3.4vw, 2.3rem);
    font-weight: 700;
    letter-spacing: -0.025em;
    text-align: center;
    margin-bottom: 40px;
}

.lp-features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 18px;
}

.lp-feature {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 22px 24px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    font-size: 0.95rem;
    line-height: 1.55;
    animation: fadeUp 0.5s ease both;
    animation-delay: var(--d, 0ms);
}

.lp-feature-mark {
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    margin-top: 8px;
    border-radius: 50%;
    background: var(--color-accent);
}

/* Screenshots, alternating side, each rising as it comes into view. */
.lp-shots { padding-bottom: 40px; }

.lp-shot {
    margin: 0 0 56px;
    max-width: 860px;
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.lp-shot.right { margin-left: auto; }
.lp-shot.in { opacity: 1; transform: none; }

.lp-shot figcaption {
    margin-top: 10px;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* ---- pricing ---- */

.lp-plans {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 18px;
    max-width: 900px;
    margin: 0 auto;
}

.lp-plan {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 28px 24px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.lp-plan.featured { border-color: var(--color-accent); box-shadow: var(--shadow-md); }
.lp-plan h3 { font-size: 1rem; font-weight: 600; }

.lp-price { font-size: 1.9rem; font-weight: 700; letter-spacing: -0.02em; }
.lp-per { font-size: 0.85rem; font-weight: 400; color: var(--color-text-muted); }
.lp-plan-points {
    flex: 1;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.88rem;
    color: var(--color-text-secondary);
}

.lp-plan-points li { position: relative; padding-left: 18px; margin-bottom: 5px; line-height: 1.5; }

.lp-plan-points li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-accent);
}

/* Badges under the version, on one line. */
.portal-badges { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 14px; }
.lp-plan form { margin-top: auto; }

/* One plan should not stretch the width of the row. A price card that wide reads as a banner, and
   the eye has to travel from the price on the left to the button on the right. */
.lp-plans:has(.price-card:only-child) {
    grid-template-columns: minmax(0, 380px);
    justify-content: center;
}

.lp-addons-note { text-align: center; margin-top: 26px; font-size: 0.9rem; color: var(--color-text-muted); }
.lp-addons-note a { color: var(--color-accent); }

/* The spec table on a landing page is centred and narrower than the product page's, which sits in
   a column of its own. */
.lp-specs .spec-table-wrap { max-width: 720px; margin: 0 auto; }


/* ---- closing ---- */

.lp-close {
    padding: 88px 0 104px;
    text-align: center;
    background: var(--color-bg);
    border-top: 1px solid var(--color-border-light);
}

.lp-close h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 700; letter-spacing: -0.03em; }
.lp-close p { max-width: 520px; margin: 12px auto 28px; color: var(--color-text-secondary); }

@media (max-width: 640px) {
    .lp-hero { padding-top: 64px; }
    .lp-section { padding: 56px 0; }
    .lp-stage { padding-bottom: 48px; }
    .lp-shot { margin-bottom: 36px; }
}

/* The registered name and organisation number, which a Norwegian business has to state where a
   customer can find them. Quiet, but on every page. */
.footer-org {
    display: block;
    margin-top: 4px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* A product's own wordmark. Lighter than the OpenHub one on purpose: the mark beside it carries the
   weight, so the name can sit quietly next to it rather than competing with it. */
.logo-product {
    font-weight: 300;
    letter-spacing: 0.01em;
}

/* ---- feature cards with a clip behind them ---- */

.lp-feature { position: relative; }
.lp-feature-title { font-weight: 500; }

.lp-feature.has-more {
    cursor: pointer;
    transition: border-color 0.18s, transform 0.18s;
}

.lp-feature.has-more:hover,
.lp-feature.has-more:focus-visible,
.lp-feature.has-more.open {
    border-color: var(--color-accent);
    transform: translateY(-2px);
    outline: none;
}

/* Sits over the grid rather than pushing it about, and points at the card it came from. */
.lp-pop {
    position: absolute;
    left: 50%;
    bottom: calc(100% + 12px);
    z-index: 20;
    width: min(360px, 78vw);
    padding: 10px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 6px) scale(0.98);
    transition: opacity 0.18s, transform 0.18s, visibility 0.18s;
    pointer-events: none;
}

.lp-feature.open .lp-pop {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0) scale(1);
}

/* Frameless: rounded corners and nothing else. No controls, no border, no shadow of its own -
   the panel around it is the frame. */
.lp-pop-clip {
    border-radius: var(--radius);
    overflow: hidden;
    background: #000;
    line-height: 0;
    aspect-ratio: 16 / 10;
}

.lp-pop-clip video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lp-pop-text {
    margin: 10px 4px 4px;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--color-text-secondary);
}

/* Cards in the last row would open off the top of a short section - flip those below instead. */
@media (max-width: 700px) {
    .lp-pop { left: 0; transform: translate(0, 6px) scale(0.98); width: 100%; }
    .lp-feature.open .lp-pop { transform: translate(0, 0) scale(1); }
}

/* ===== Roadmap board - the same shape on the public page and in Admin ===== */
.board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; align-items: start; }

.board-head {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.78rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
    margin-bottom: 12px;
}

.board-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.board-dot.requested { background: #9aa4b2; }
.board-dot.planned { background: #2563eb; }
.board-dot.in_progress { background: #f5a524; }
.board-dot.done { background: #16a34a; }

.board-count { margin-left: auto; font-weight: 500; opacity: 0.6; }

.board-card {
    padding: 14px 16px;
    border-radius: 10px;
    margin-bottom: 10px;
}

.board-card-title { font-weight: 600; font-size: 0.92rem; line-height: 1.4; }
.board-card-body { margin-top: 6px; font-size: 0.85rem; line-height: 1.55; }

@media (max-width: 900px) { .board { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .board { grid-template-columns: 1fr; } }

.board-head { color: var(--color-text-muted); }
.board-card { background: var(--color-surface); border: 1px solid var(--color-border-light); }
.board-card-body { color: var(--color-text-secondary); }
.board-empty { color: var(--color-border); text-align: center; padding: 12px 0; }

/* ===== Portal on a phone =====
   The desktop layout assumes a row has room for a heading on the left and a button on the right.
   At 400px it does not, so the rows stack and the buttons take the width they are given rather than
   sitting in the middle of an empty line. */

@media (max-width: 640px) {
    /* Heading, address, then the button - in that order, and the button no wider than its label. */
    .portal-header {
        align-items: flex-start;
        gap: 12px;
        margin-bottom: 20px;
    }

    .portal-header .btn,
    .portal-header .portal-actions .btn { width: auto; }

    /* Action rows: two buttons side by side is fine, three is not - let them wrap and fill. */
    .portal-actions { gap: 8px; }
    .portal-actions .btn { flex: 1 1 auto; min-width: 46%; text-align: center; }

    /* A button alone on a line reads as an afterthought when it hugs the right edge. */
    .portal-toolbar { justify-content: stretch; }
    .portal-toolbar .btn { width: 100%; }

    /* The licence key is the widest fixed thing on the page - let it shrink rather than push. */
    .portal-key-field { max-width: 100%; }
    .portal-key-reveal summary { padding-left: 10px; gap: 8px; }
    .portal-key-stack > .portal-key { font-size: 0.74rem; letter-spacing: 0.04em; }
    .portal-key-masked { letter-spacing: 0.1em; }

    /* Interface drawings inside a guide: full size they dominate a narrow column and wrap badly. */
    .ui-btn, .ui-select, .ui-nav, .ui-seg { font-size: 0.76rem; }
    .ui-btn { padding: 5px 10px; }
    .ui-seg-item { padding: 4px 9px; }
    .ui-nav { padding: 5px 10px 5px 13px; }
    .ui-select { padding: 5px 9px; gap: 7px; }

    /* Steps: the circle can come in a little so the text has room for a long line. */
    .portal-article .md-steps > li { padding-left: 36px; }
    .portal-article .md-steps > li::before { width: 24px; height: 24px; font-size: 0.75rem; }

    /* An anchor jump must not land under the fixed navbar. */
    [id] { scroll-margin-top: 80px; }
}

.portal-toolbar { display: flex; justify-content: flex-end; margin-bottom: 14px; }

/* The two claims that are true of every card and obvious from none of them. */
.board-notes { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 34px; }

/* The cards are the content and get the bright surface; these two sit back on the page's own
   background. It reads the right way round - the board is what you came for, these are the frame -
   and it works in both themes, which tinting could not: in light mode the cards are already white,
   so there is no lighter left to go. */
.board-note {
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.board-note b {
    display: block;
    margin-bottom: 4px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}
.board-note p { font-size: 0.88rem; color: var(--color-text-secondary); line-height: 1.55; }


@media (max-width: 700px) { .board-notes { grid-template-columns: 1fr; } }

/* "What is coming", straight under the hero on a product's own page. */
.lp-coming { padding: 0 0 24px; }

.lp-coming-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
}

.lp-coming-head h2 { font-size: 1.15rem; font-weight: 600; letter-spacing: -0.01em; }
.lp-coming-head a { font-size: 0.85rem; color: var(--color-accent); white-space: nowrap; }

.lp-coming-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 12px;
}

.lp-coming-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
}

.lp-coming-item .board-dot { margin-top: 7px; }
.lp-coming-item b { font-size: 0.9rem; font-weight: 600; line-height: 1.4; }

.lp-coming-item p {
    margin-top: 4px;
    font-size: 0.83rem;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

/* Thumbs up on a roadmap card. Quiet until you hover it, and clearly on once you have voted -
   the count alone cannot say whether the vote in it is yours. */
.board-vote-form { margin-top: 10px; }

.board-vote {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 8px;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--color-text-muted);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.board-vote svg { width: 14px; height: 14px; }

.board-vote:hover {
    color: var(--color-accent);
    border-color: var(--color-accent);
}

.board-vote.voted {
    color: #fff;
    background: var(--color-accent);
    border-color: var(--color-accent);
}

.board-vote.voted:hover { color: #fff; opacity: 0.9; }

/* The roadmap opens on its heading, not on a hero, so it needs a good deal less headroom than a
   product page does - 64px of the padding is under the fixed navbar either way. */
.board-page { padding-top: 96px; }

/* Roadmap toolbar: filter on the left, order on the right. */
.board-toolbar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 20px;
}

.board-search { flex: 1; min-width: 220px; margin-bottom: 0; }
.board-sort { margin-bottom: 0; flex-shrink: 0; }

/* An empty column shows its dash again when a filter empties it, so the column keeps its shape. */
.board-empty[hidden], .board-card[hidden] { display: none; }

/* Vote on the left, version on the right, one line. */
.board-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 10px;
}

.board-card-foot .board-vote-form { margin-top: 0; }

.board-card-version {
    margin-left: auto;
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

/* Bulleted points on a roadmap card - the same dot the pricing lists use, so a point reads the
   same wherever it appears. */
.board-card-points {
    margin: 5px 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--color-text-secondary);
}

.board-card-points li { position: relative; padding-left: 16px; margin-bottom: 4px; }

.board-card-points li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--color-accent);
}

/* Heading on the left, the suggestion button level with it on the right - that half of the line is
   empty otherwise. */
.board-head-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    margin-bottom: 32px;
}

.board-head-row > div { min-width: 260px; }

/* Closed it is a button; opened it claims a row of its own so the form drops below the heading
   instead of squeezing it. */
.board-suggest { margin: 0; flex-shrink: 0; }
.board-suggest[open] { flex-basis: 100%; max-width: 560px; margin-left: auto; }

.board-suggest > summary {
    display: inline-flex;
    align-items: center;
    padding: 9px 16px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text);
    cursor: pointer;
    list-style: none;
}

.board-suggest > summary::-webkit-details-marker { display: none; }
.board-suggest > summary:hover { border-color: var(--color-accent); color: var(--color-accent); }
.board-suggest[open] > summary { margin-bottom: 12px; }

/* ===== The public guide =====
   A side menu that stays put and one column of reading beside it. The menu is the navigation, so it
   is on the index and on every article - never a page you have to go back to. */
.guide-page { padding-top: 96px; }

.guide-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 48px;
    align-items: start;
    /* Centred as a block. The menu plus a column of reading is narrower than the page, and left
       against the edge it read as though the rest of the page had failed to load. */
    max-width: 940px;
    margin: 0 auto;
}

/* Sticky under the fixed navbar, and scrollable on its own once the list outgrows the screen. */
.guide-side {
    position: sticky;
    top: 88px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.guide-side a {
    padding: 6px 10px;
    border-radius: var(--radius);
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--color-text-secondary);
    text-decoration: none;
}

.guide-side a:hover { background: var(--color-surface); color: var(--color-text); }
.guide-side a.active { background: var(--color-surface); color: var(--color-accent); font-weight: 600; }
.guide-side-home { font-weight: 600; color: var(--color-text); margin-bottom: 8px; }

.guide-side-group {
    margin: 18px 0 4px;
    padding: 0 10px;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.guide-main { min-width: 0; }
.guide-main .portal-article h1 { font-size: 2rem; margin-bottom: 18px; letter-spacing: -0.02em; }

/* The index: every article with the first line of it, so the list says what is inside. */
.guide-index-head {
    font-size: 0.95rem;
    font-weight: 600;
    margin: 28px 0 12px;
}

.guide-index { display: grid; gap: 10px; }

.guide-index a {
    display: block;
    padding: 14px 16px;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    text-decoration: none;
}

.guide-index a:hover { border-color: var(--color-accent); }
.guide-index b { display: block; font-size: 0.95rem; color: var(--color-text); }
.guide-index span { display: block; margin-top: 4px; font-size: 0.85rem; color: var(--color-text-muted); }

/* Previous and next, at the foot of an article, running straight through the menu. */
.guide-nav {
    display: flex;
    gap: 12px;
    margin-top: 48px;
    padding-top: 24px;
    border-top: 1px solid var(--color-border-light);
}

.guide-nav a {
    flex: 1;
    padding: 12px 16px;
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    text-decoration: none;
}

.guide-nav a:hover { border-color: var(--color-accent); }
.guide-nav-next { text-align: right; }
.guide-nav span { display: block; font-size: 0.75rem; color: var(--color-text-muted); }
.guide-nav b { display: block; margin-top: 2px; font-size: 0.9rem; color: var(--color-text); }

/* On a phone the menu is a list above the article rather than a column beside it. */
@media (max-width: 860px) {
    .guide-layout { grid-template-columns: 1fr; gap: 28px; }
    .guide-side { position: static; max-height: none; }
    .guide-nav { flex-direction: column; }
    .guide-nav-next { text-align: left; }
}
