/* ==========================================================================
   Adam Keyte Portfolio - Shared Stylesheet
   ========================================================================== */

/* --- Custom Properties --- */
:root {
    --color-primary: #0073A8;
    --color-primary-dark: #005580;
    --color-primary-hover: #1565a0;
    --color-accent: #6B6800;
    --color-accent-muted: #7A7500;
    --color-text: #333;
    --color-text-secondary: #555;
    --color-text-muted: #666;
    --color-text-light: #767676;
    --color-bg: #f7f8f9;
    --color-bg-card: #fff;
    --color-bg-subtle: #eef1f3;
    --color-border: #dce0e4;
    --color-shadow: rgba(0, 0, 0, 0.1);
    --font-stack: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    --font-heading: 'Outfit', var(--font-stack);
    --max-width: 1200px;
    --nav-height: 56px;
}

/* --- Reset --- */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* --- Base Typography --- */
body {
    font-family: var(--font-stack);
    line-height: 1.6;
    color: var(--color-text);
    background: var(--color-bg);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
}

.nav-site-name,
nav h1,
.badge,
.cta-button,
.tag,
.role,
.meta-label {
    font-family: var(--font-heading);
}

/* --- Focus Styles --- */
a:focus-visible,
button:focus-visible,
.cta-button:focus-visible,
.project-card:focus-visible,
.nav-button:focus-visible,
.back-link:focus-visible {
    outline: 3px solid var(--color-primary-dark);
    outline-offset: 2px;
}

/* Invert focus color on dark backgrounds */
.gradient-header a:focus-visible,
.gradient-header button:focus-visible {
    outline-color: white;
}

/* --- Skip Navigation --- */
.skip-link {
    position: absolute;
    top: -100%;
    left: 1rem;
    background: var(--color-primary-dark);
    color: white;
    padding: 0.75rem 1.5rem;
    border-radius: 0 0 5px 5px;
    font-weight: 600;
    z-index: 10000;
    text-decoration: none;
    transition: top 0.2s;
}

.skip-link:focus {
    top: 0;
}

/* --- Screen Reader Only Utility --- */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --- Shared Animations --- */
@keyframes gradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

@keyframes pulse {
    0%, 100% { transform: scale(1); opacity: 0.5; }
    50% { transform: scale(1.1); opacity: 0.3; }
}

/* --- Navigation --- */
nav {
    background: var(--color-bg-card);
    padding: 1rem 0;
    position: sticky;
    top: 0;
    box-shadow: 0 2px 4px var(--color-shadow);
    z-index: 1000;
}

nav .container {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

nav h1,
.nav-site-name {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-primary);
}

nav h1 a,
.nav-site-name a {
    text-decoration: none;
    color: inherit;
}

nav ul {
    list-style: none;
    display: flex;
    gap: 2rem;
}

nav a {
    text-decoration: none;
    color: var(--color-text-secondary);
    font-weight: 500;
    transition: color 0.3s;
}

nav a:hover {
    color: var(--color-primary);
}

.back-link {
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.back-link:hover {
    text-decoration: underline;
}

/* --- Gradient Header (shared by hero + project headers) --- */
.gradient-header {
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent-muted) 100%);
    background-size: 200% 200%;
    animation: gradientShift 15s ease infinite;
    color: white;
    position: relative;
    overflow: hidden;
}

/* Semi-transparent overlay to ensure text contrast across gradient */
.gradient-header::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.15);
    pointer-events: none;
}

.gradient-header::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
    animation: pulse 10s ease-in-out infinite;
}

/* --- CTA Button --- */
.cta-button {
    display: inline-block;
    padding: 0.8rem 2rem;
    background: white;
    color: var(--color-primary);
    text-decoration: none;
    border-radius: 5px;
    font-weight: 600;
    transition: transform 0.3s, box-shadow 0.3s;
    position: relative;
    z-index: 1;
}

.cta-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
}

.cta-button-outline {
    display: inline-block;
    padding: 0.8rem 2rem;
    background: transparent;
    color: var(--color-primary);
    text-decoration: none;
    border: 2px solid var(--color-primary);
    border-radius: 50px;
    font-weight: 600;
    font-family: var(--font-heading);
    transition: background 0.3s, color 0.3s;
    position: relative;
    z-index: 1;
}

.cta-button-outline:hover {
    background: var(--color-primary);
    color: white;
}

/* --- Footer --- */
footer {
    background: var(--color-primary-dark);
    color: white;
    text-align: center;
    padding: 1.5rem;
    margin-top: 0;
    font-size: 0.9rem;
}

/* ==========================================================================
   Portfolio Index Styles
   ========================================================================== */

/* --- Sections --- */
section {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 3rem 2rem;
    /* Keep anchor jumps clear of the sticky site nav. Project pages add a
       second sticky bar and override this in project.css. */
    scroll-margin-top: calc(var(--nav-height) + 0.5rem);
}

section + section {
    border-top: 1px solid var(--color-border);
}

section h2 {
    font-size: 1.75rem;
    margin-bottom: 1.5rem;
    color: var(--color-primary);
    border-bottom: 3px solid var(--color-primary);
    padding-bottom: 0.5rem;
    display: inline-block;
}

/* --- Hero Section --- */
#hero {
    text-align: center;
    padding: 3rem 2rem 2.5rem;
    max-width: none;
    margin: 0;
}

#hero h1 {
    font-size: 2.4rem;
    margin-bottom: 0.5rem;
    position: relative;
    z-index: 1;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

#hero p {
    font-size: 1.15rem;
    margin-bottom: 1.25rem;
    opacity: 0.95;
    position: relative;
    z-index: 1;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

/* --- Specialty Badges --- */
.specialty-badges {
    display: flex;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 1rem auto 1.5rem;
    max-width: 800px;
    position: relative;
    z-index: 1;
}

.badge {
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    border: 2px solid rgba(255, 255, 255, 0.3);
    padding: 0.8rem 1.5rem;
    border-radius: 50px;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    font-weight: 600;
    font-size: 0.95rem;
    transition: all 0.3s ease;
    color: white;
}

.badge:hover {
    background: rgba(255, 255, 255, 0.25);
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}

/* Badges are links that apply a lens (js/lens.js). The active lens's badge
   is inverted and marked aria-current; clicking it returns to the default
   view. Links, not buttons, so keyboard and screen-reader users get the
   same affordance sighted mouse users see. */
a.badge {
    text-decoration: none;
    cursor: pointer;
}

.badge-active {
    background: #fff;
    color: var(--color-primary-dark);
    border-color: #fff;
}

.badge-active:hover {
    background: rgba(255, 255, 255, 0.9);
}

.badge-icon {
    font-size: 1.3rem;
}

/* --- About Section --- */
#about p {
    font-size: 1.1rem;
    line-height: 1.8;
    max-width: 70ch;
    color: var(--color-text-secondary);
    margin-bottom: 1.5rem;
}

/* AI experiments intro: two paragraphs, read like About. */
[data-lens="design-lab-intro"] p {
    line-height: 1.8;
    max-width: 70ch;
    color: var(--color-text-secondary);
    margin: 0 0 1rem;
}

[data-lens="design-lab-intro"] {
    margin-bottom: 1.5rem;
}

/* A shorter nav label on narrow screens, where the long one wraps the
   menu onto two lines and throws off the anchor offsets. Only one label is
   ever displayed, so assistive tech reads one name. */
.nav-label-short {
    display: none;
}

[data-lens="nav"] a {
    white-space: nowrap;
}

@media (max-width: 768px) {
    .nav-label-long {
        display: none;
    }

    .nav-label-short {
        display: inline;
    }
}

/* Wrapping: headings even out their lines; paragraphs avoid ending on a
   single orphaned word. Browsers without support ignore both. */
h1, h2, h3, h4, h5 {
    text-wrap: balance;
}

p, li, figcaption, blockquote {
    text-wrap: pretty;
}

/* --- Projects Grid --- */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
    margin-top: 2rem;
}

/* The [hidden] attribute must win over display:flex/grid below - the lens
   system sets it to curate which projects a given lens shows. */
[hidden] {
    display: none !important;
}

/* Route back to the unfiltered portfolio. Revealed by js/lens.js only when a
   lens actually hides something; see docs/capabilities.md, lens visibility. */
.full-index-link {
    margin-top: 1.75rem;
    font-size: 0.95rem;
}

.project-card {
    background: var(--color-bg-card);
    border-radius: 8px;
    padding: 1.75rem;
    border: 1px solid var(--color-border);
    transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    position: relative;
}

.project-card.no-link {
    cursor: default;
}

.project-card:hover {
    border-color: var(--color-primary);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
    transform: translateY(-3px);
}

.project-card.no-link:hover {
    border-color: var(--color-border);
    box-shadow: none;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .project-card:hover {
        transform: none;
    }
}

.project-card::after {
    content: "View Details \2192";
    display: block;
    margin-top: auto;
    padding-top: 1rem;
    color: var(--color-primary);
    font-weight: 600;
    font-size: 0.9rem;
}

.project-card.no-link::after {
    content: none;
}

.project-card:hover::after {
    text-decoration: underline;
}

.project-card h3 {
    color: var(--color-primary);
    font-size: 1.2rem;
    margin-bottom: 0.4rem;
}

.project-card .role {
    color: var(--color-accent);
    font-weight: 600;
    font-size: 0.85rem;
    margin-bottom: 0.75rem;
    display: block;
}

.project-card p {
    color: var(--color-text-muted);
    font-size: 0.92rem;
    line-height: 1.65;
    margin-bottom: 1rem;
}

.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.tag {
    background: var(--color-bg-subtle);
    padding: 0.25rem 0.7rem;
    border-radius: 15px;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border);
}

/* The tag matching the active lens (set by js/lens.js). Weight carries the
   emphasis as well as colour. */
.tag.tag-active {
    background: #e6f1f7;
    color: var(--color-primary-dark);
    border-color: var(--color-primary);
    font-weight: 700;
}

/* --- Skills Section --- */
.skills-container {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    margin-top: 2rem;
}

.skill-category {
    background: var(--color-bg-card);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid var(--color-border);
}

.skill-category h3 {
    color: var(--color-accent);
    font-size: 1rem;
    margin-bottom: 1rem;
}

.skill-category ul {
    list-style: none;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.skill-category li {
    background: var(--color-bg);
    padding: 0.35rem 0.85rem;
    border-radius: 20px;
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border);
    line-height: 1.4;
}

.skill-category li::before {
    display: none;
}

/* --- Contact Section --- */
#contact {
    background: var(--color-bg-card);
    border-radius: 8px;
    padding: 3rem;
    box-shadow: 0 2px 8px var(--color-shadow);
}

.contact-info {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-width: 600px;
    margin: 2rem auto 0;
}

.contact-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1.2rem;
    background: var(--color-bg);
    border-radius: 50px;
    border: 1px solid var(--color-border);
}

.contact-item strong {
    min-width: 100px;
    color: var(--color-primary);
}

.contact-item a {
    color: var(--color-primary);
    text-decoration: none;
}

.contact-item a:hover {
    text-decoration: underline;
}

.contact-item[hidden] {
    display: none;
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 768px) {
    nav .container {
        flex-direction: column;
        gap: 1rem;
    }

    nav ul {
        gap: 0.5rem;
    }

    nav a {
        padding: 0.5rem 0.75rem;
    }

    #hero {
        padding: 2rem 1.5rem 1.5rem;
    }

    #hero h1 {
        font-size: 1.6rem;
    }

    #hero p {
        font-size: 1rem;
    }

    .specialty-badges {
        gap: 0.75rem;
    }

    .badge {
        padding: 0.5rem 1rem;
        font-size: 0.85rem;
    }
}

/* ==========================================================================
   Accessibility: Respect reduced motion preference
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    .badge:hover,
    .project-card:hover,
    .cta-button:hover {
        transform: none;
    }
}

/* Card thumbnails. Added 2026-10-16: the index was seven text-only cards, which
   is the first screen a hirer sees and read as a wall of bullets. Every image
   chosen is interface or systems work rather than character or environment art,
   so the page shows what Adam designed and claims no credit for an artist's. */
.card-media {
    margin: -1.75rem -1.75rem 1.25rem;
    border-radius: 0 8px 0 0;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: var(--color-bg-subtle);
}

.card-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    transition: transform 0.4s ease;
}

.project-card:hover .card-media img {
    transform: scale(1.04);
}

/* A card with no surviving asset keeps its top padding rather than opening on
   a gap: Doctor Who was cancelled at studio closure and nothing shippable
   survives, which is honest rather than a hole to fill. */
.project-card:not(:has(.card-media)) {
    padding-top: 1.75rem;
}

@media (prefers-reduced-motion: reduce) {
    .card-media img,
    .project-card:hover .card-media img {
        transition: none;
        transform: none;
    }
}

/* Project pages: keep the site name and the back link on one row at phone
   widths. Stacking them made the stuck bar twice the height it needs to be.
   The index nav, which has a link list rather than a back link, is unchanged. */
@media (max-width: 768px) {
    nav .container:has(> .back-link) {
        flex-direction: row;
        justify-content: space-between;
        align-items: center;
        padding: 0 1.25rem;
    }

    nav .container:has(> .back-link) .nav-site-name {
        font-size: 1.2rem;
        white-space: nowrap;
    }

    nav .container:has(> .back-link) .back-link {
        font-size: 0.95rem;
        white-space: nowrap;
    }
}

/* Rights notice under the copyright line on portfolio pages, which show
   third-party screenshots and box art. Deliberately not "fair use": that is
   a US doctrine, and this is a UK site. */
.footer-notice {
    max-width: 46rem;
    margin: 0.5rem auto 0;
    font-size: 0.8rem;
    opacity: 0.85;
}

/* Portfolio hero: a wall of the shipped titles' box art under the brand
   gradient. Added 2026-10-18. The wash is 82% opaque, measured against every
   pixel of the mosaic so the white subtitle never drops below 4.5:1 (worst
   case 4.56:1, before the text shadow). Static: the old gradient drift is
   switched off here, so nothing moves behind text. */
#hero.gradient-header {
    background:
        linear-gradient(135deg, rgba(0, 85, 128, 0.82) 0%, rgba(122, 117, 0, 0.82) 100%),
        url("/images/hero_box_art_mosaic.jpg?v=2026-10-18b") center / cover no-repeat,
        #0b2233;
    animation: none;
    padding: 2.25rem 2rem 2rem;
}

#hero.gradient-header::before {
    display: none;
}

@media (max-width: 768px) {
    #hero.gradient-header {
        background:
            linear-gradient(135deg, rgba(0, 85, 128, 0.82) 0%, rgba(122, 117, 0, 0.82) 100%),
            url("/images/hero_box_art_mosaic_small.jpg?v=2026-10-18b") center / cover no-repeat,
            #0b2233;
        padding: 1.75rem 1.25rem 1.5rem;
    }
}
