/*
Theme Name: Lumen
Author: Donncha O Caoimh
Author URI: https://odd.blog/
Description: A dark, gallery-first photography theme for photoblogs. Features a responsive CSS Grid layout, featured image hover overlays, and a dedicated section for text-only posts at the bottom of archive pages.
Version: 1.2.0
Requires at least: 6.0
Tested up to: 6.6
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lumen
Tags: blog, photography, one-column, grid-layout, custom-colors, custom-menu, featured-images, editor-style, translation-ready, sticky-post, threaded-comments
*/

/* ========== CSS RESET & BASE ========== */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    --bg-primary: #0a0a0a;
    --bg-secondary: #111111;
    --bg-tertiary: #1a1a1a;
    --text-primary: #e5e5e5;
    --text-secondary: #888888;
    /* #7c7c7c gives 4.74:1 against --bg-primary. The previous #555555 was
       2.64:1 and failed WCAG AA everywhere it was used. */
    --text-muted: #7c7c7c;
    --border: #1a1a1a;
    --border-hover: #333333;
    --accent: #ffffff;
    --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
    --transition: 0.3s ease;
}

html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-body);
    background-color: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
    min-height: 100vh;
    /* 100vw includes the scrollbar, so .alignfull would otherwise add a
       horizontal scrollbar of its own. */
    overflow-x: hidden;
}

a {
    color: var(--text-secondary);
    text-decoration: none;
    transition: color var(--transition);
}

a:hover {
    color: var(--accent);
}

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

/* ========== HEADER ========== */
.site-header {
    text-align: center;
    padding: 2rem 1.5rem;
    border-bottom: 1px solid var(--border);
}

.site-title {
    font-size: 2.5rem;
    font-weight: 200;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    margin: 0;
    color: var(--accent);
}

.site-title a {
    color: var(--accent);
}

.site-description {
    color: var(--text-secondary);
    font-size: 0.9rem;
    letter-spacing: 0.1em;
    margin-top: 0.5rem;
}

.site-nav {
    margin-top: 1.5rem;
}

.site-nav a {
    color: var(--text-secondary);
    margin: 0 1rem;
    font-size: 0.85rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.site-nav a:hover {
    color: var(--accent);
}

/* ========== MAIN LAYOUT ========== */
.site-main {
    padding: 2rem 1.5rem;
    max-width: 1400px;
    margin: 0 auto;
}

/* ========== PHOTO GRID ========== */
.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.5rem;
    /* Grid items stretch by default, and stretch beats aspect-ratio. Without
       this, one portrait card sets its row's height and every landscape card
       beside it gets stretched to 3:4 and cropped by object-fit. Rows end
       ragged instead, which is the point of having portrait cards at all. */
    align-items: start;
}

.photo-card {
    position: relative;
    overflow: hidden;
    border-radius: 4px;
    background: var(--bg-tertiary);
    aspect-ratio: 4 / 3;
}

/* Tall photos get the portrait crop from lumen-grid-portrait. Without this the
   card stays 4:3 and crops the portrait image back to landscape, losing more of
   the frame than using the landscape size would have. */
.photo-card--portrait {
    aspect-ratio: 3 / 4;
}

/* The anchor fills the card so the whole tile is clickable, not just the
   inline box around the image. */
.photo-card a {
    display: block;
    width: 100%;
    height: 100%;
}

/* The anchor's border box is exactly the card's padding box, and the card
   clips overflow, so a positive outline-offset would be clipped away and the
   focus ring would be invisible. Draw it inside instead. */
.photo-card a:focus-visible {
    outline-offset: -4px;
}

.photo-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.photo-card:hover img {
    transform: scale(1.05);
}

.photo-card-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 3rem 1.5rem 1.5rem;
    background: linear-gradient(transparent, rgba(0,0,0,0.85));
    opacity: 0;
    transition: opacity var(--transition);
}

.photo-card:hover .photo-card-overlay,
.photo-card:focus-within .photo-card-overlay {
    opacity: 1;
}

/* Touch devices have no hover, so the title and date would otherwise never be
   readable. Show the overlay permanently there. */
@media (hover: none) {
    .photo-card-overlay {
        opacity: 1;
    }
}

.photo-card-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 400;
    color: var(--accent);
    line-height: 1.3;
    /* Keep a very long title from growing the panel over the whole photo. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.photo-card-date {
    color: var(--text-secondary);
    font-size: 0.8rem;
    margin-top: 0.25rem;
    display: block;
}

/* ========== TEXT-ONLY POSTS SECTION ========== */
.text-posts-section {
    margin-top: 4rem;
    padding-top: 3rem;
    border-top: 1px solid var(--border);
}

.text-posts-heading {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--text-muted);
    margin-bottom: 2rem;
    font-weight: 400;
}

.text-posts-list {
    display: grid;
    gap: 1rem;
}

.text-post-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.2rem 1.5rem;
    background: var(--bg-secondary);
    border-radius: 4px;
    border: 1px solid var(--border);
    transition: all var(--transition);
}

.text-post-item:hover {
    border-color: var(--border-hover);
}

.text-post-item:hover .text-post-title {
    color: var(--accent);
}

.text-post-title {
    font-size: 1rem;
    color: var(--text-primary);
    transition: color var(--transition);
}

.text-post-date {
    color: var(--text-muted);
    font-size: 0.8rem;
    white-space: nowrap;
    margin-left: 1rem;
}

/* ========== SINGLE POST ========== */
.single-header {
    text-align: center;
    padding: 3rem 1.5rem 2rem;
    max-width: 900px;
    margin: 0 auto;
}

.single-title {
    font-size: 2rem;
    font-weight: 300;
    letter-spacing: 0.02em;
    margin-bottom: 0.5rem;
}

.single-meta {
    color: var(--text-muted);
    font-size: 0.85rem;
}

.single-featured-image {
    max-width: 1400px;
    margin: 0 auto 3rem;
    padding: 0 1.5rem;
}

/* No width:100% here. It stretched every featured image to fill the 1304px
   content box, so anything narrower was upscaled: a portrait frame served at
   607px was blown up by 115%. The base img rule caps width at the container,
   and auto margins centre whatever is narrower. */
.single-featured-image img {
    margin-left: auto;
    margin-right: auto;
    border-radius: 4px;
}

.single-content {
    max-width: 700px;
    margin: 0 auto;
    padding: 0 1.5rem 4rem;
    font-size: 1.05rem;
    line-height: 1.8;
    color: var(--text-primary);
}

.single-content p {
    margin-bottom: 1.5rem;
}

.single-content a {
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-hover);
}

.single-content a:hover {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* ========== NAVIGATION ========== */
.post-navigation {
    max-width: 700px;
    margin: 0 auto 4rem;
    padding: 0 1.5rem;
    display: flex;
    justify-content: space-between;
    gap: 1rem;
}

.nav-previous,
.nav-next {
    flex: 1;
}

.nav-next {
    text-align: right;
    /* Keeps "Next" on the right when there is no previous post to balance it. */
    margin-left: auto;
}

.nav-label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    margin-bottom: 0.25rem;
}

.nav-title {
    color: var(--text-primary);
    font-size: 0.95rem;
}

/* ========== POST TAGS ========== */
/* Sibling of .single-content rather than a child, so the post body and its
   metadata stay separate. Repeats max-width and padding the way
   .post-navigation does. */
.post-tags {
    max-width: 700px;
    margin: 0 auto 3rem;
    padding: 0 1.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.post-tags a {
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-muted);
    font-size: 0.8rem;
    letter-spacing: 0.05em;
    padding: 0.35rem 0.75rem;
    transition: border-color var(--transition), color var(--transition);
}

/* focus-visible shares the hover treatment: 1.0.2 restored the keyboard focus
   ring on gallery links, and a hover-only affordance here would undo that. */
.post-tags a:hover,
.post-tags a:focus-visible {
    border-color: var(--border-hover);
    color: var(--accent);
}

/* ========== FOOTER ========== */
.site-footer {
    text-align: center;
    padding: 3rem 2rem;
    color: var(--text-muted);
    font-size: 0.8rem;
    border-top: 1px solid var(--border);
}

/* ========== PAGINATION ========== */
.pagination {
    text-align: center;
    padding: 3rem 0;
}

.pagination a,
.pagination span {
    display: inline-block;
    padding: 0.5rem 1rem;
    margin: 0 0.25rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.pagination a:hover {
    border-color: var(--border-hover);
    color: var(--accent);
}

.pagination .current {
    background: var(--bg-secondary);
    color: var(--accent);
    border-color: var(--border-hover);
}

/* ========== MULTIPAGE POST LINKS ========== */
/* wp_link_pages() output, kept separate from .pagination so it does not
   inherit the pager's bordered boxes. */
.page-links {
    color: var(--text-muted);
    font-size: 0.9rem;
    margin-bottom: 2rem;
}

.page-links a,
.page-links > span {
    margin-left: 0.5rem;
}

.single-content .page-links a {
    border-bottom: 0;
}

/* ========== 404 & NO POSTS ========== */
.no-posts {
    text-align: center;
    padding: 6rem 1.5rem;
    color: var(--text-muted);
}

.no-posts h1,
.no-posts h2 {
    font-weight: 300;
    margin-bottom: 1rem;
    color: var(--text-primary);
}

/* ========== ACCESSIBILITY HELPERS ========== */
/* Required by WordPress: the_posts_pagination() and get_search_form() both
   emit .screen-reader-text. Without this rule the pager reads
   "Page 1 Page 2 Page 3" and a stray "Posts navigation" heading appears. */
.screen-reader-text {
    border: 0;
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    word-wrap: normal !important;
}

.screen-reader-text:focus {
    background-color: var(--bg-secondary);
    border-radius: 4px;
    box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
    clip-path: none;
    color: var(--accent);
    display: block;
    font-size: 0.9rem;
    height: auto;
    left: 1rem;
    line-height: normal;
    padding: 0.9rem 1.2rem;
    text-decoration: none;
    top: 1rem;
    width: auto;
    z-index: 100000;
}

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

/* ========== ARCHIVE & SEARCH HEADERS ========== */
.archive-header {
    text-align: center;
    margin-bottom: 3rem;
}

.archive-title {
    font-size: 1.2rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--text-muted);
    font-weight: 400;
}

.archive-description {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-top: 0.75rem;
}

.search-term {
    color: var(--text-primary);
}

/* ========== SEARCH FORM ========== */
.search-form {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    margin: 2rem auto 0;
    max-width: 420px;
}

.search-field {
    flex: 1;
    padding: 0.7rem 1rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.95rem;
}

.search-field::placeholder {
    color: var(--text-muted);
}

.search-submit {
    padding: 0.7rem 1.2rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-hover);
    border-radius: 4px;
    color: var(--text-primary);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    transition: color var(--transition), border-color var(--transition);
}

.search-submit:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.no-posts-back {
    margin-top: 2rem;
}

/* ========== WORDPRESS CORE CLASSES ========== */
/* Required by the theme review guidelines. Captions and floated images are a
   core use case for a photo theme, so these are not decorative. */
.alignleft {
    float: left;
    margin: 0.5rem 1.5rem 1rem 0;
}

.alignright {
    float: right;
    margin: 0.5rem 0 1rem 1.5rem;
}

.aligncenter {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

.alignnone {
    margin: 1.5rem 0;
}

/* Contain the floats above, otherwise a tall floated image overlaps whatever
   heading follows it. */
.single-content::after {
    content: "";
    display: table;
    clear: both;
}

/* Only widen once the viewport can actually hold it, otherwise the negative
   margins push content off-screen. */
@media (min-width: 1140px) {
    .single-content .alignwide {
        max-width: 1100px;
        margin-left: calc(50% - 550px);
        margin-right: calc(50% - 550px);
        width: auto;
    }
}

.single-content .alignfull {
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: auto;
}

.wp-caption {
    max-width: 100%;
    margin-bottom: 1.5rem;
}

.wp-caption img {
    border-radius: 4px;
}

/* Declaring html5 'gallery' support suppresses core's inline #gallery-N
   styles, so a [gallery] shortcode has no layout of its own without this. */
.gallery {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(3, 1fr);
    margin: 0 0 2rem;
}

.gallery-columns-1 { grid-template-columns: 1fr; }
.gallery-columns-2 { grid-template-columns: repeat(2, 1fr); }
.gallery-columns-4 { grid-template-columns: repeat(4, 1fr); }
.gallery-columns-5 { grid-template-columns: repeat(5, 1fr); }
.gallery-columns-6 { grid-template-columns: repeat(6, 1fr); }
.gallery-columns-7 { grid-template-columns: repeat(7, 1fr); }
.gallery-columns-8 { grid-template-columns: repeat(8, 1fr); }
.gallery-columns-9 { grid-template-columns: repeat(9, 1fr); }

.gallery-item {
    margin: 0;
}

.gallery-icon img {
    border-radius: 4px;
    width: 100%;
}

.wp-caption-text,
.gallery-caption,
.single-content figcaption,
.wp-element-caption {
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.5;
    margin-top: 0.6rem;
    text-align: center;
}

.sticky .photo-card-overlay,
.photo-card.sticky .photo-card-overlay {
    opacity: 1;
}

.sticky {
    outline: 1px solid var(--border-hover);
    outline-offset: 0;
}

/* Core's HTML5 comment walker emits <b class="fn"> for the author name. There
   is no .comment-author-name class anywhere in core. */
.bypostauthor > .comment-body .fn {
    color: var(--accent);
}

/* ========== POST CONTENT TYPOGRAPHY ========== */
/* The universal reset at the top zeroes margin and padding on everything, so
   anything richer than a paragraph needs its spacing restored here. */
.single-content h1,
.single-content h2,
.single-content h3,
.single-content h4,
.single-content h5,
.single-content h6 {
    font-weight: 400;
    line-height: 1.3;
    margin: 2.5rem 0 1rem;
}

.single-content h1 { font-size: 1.9rem; }
.single-content h2 { font-size: 1.6rem; }
.single-content h3 { font-size: 1.3rem; }
.single-content h4 { font-size: 1.1rem; }
.single-content h5,
.single-content h6 { font-size: 1rem; }

.single-content ul,
.single-content ol {
    margin: 0 0 1.5rem;
    padding-left: 1.6rem;
}

.single-content li {
    margin-bottom: 0.5rem;
}

.single-content li > ul,
.single-content li > ol {
    margin: 0.5rem 0 0;
}

.single-content blockquote {
    border-left: 2px solid var(--border-hover);
    color: var(--text-secondary);
    font-style: italic;
    margin: 2rem 0;
    padding: 0.25rem 0 0.25rem 1.5rem;
}

.single-content blockquote p:last-child {
    margin-bottom: 0;
}

.single-content pre {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.9rem;
    line-height: 1.6;
    margin: 0 0 1.5rem;
    overflow-x: auto;
    padding: 1.2rem;
}

.single-content code {
    background: var(--bg-secondary);
    border-radius: 3px;
    font-size: 0.9em;
    padding: 0.15em 0.4em;
}

.single-content pre code {
    background: none;
    padding: 0;
}

.single-content figure,
.single-content .wp-block-image {
    margin: 0 0 2rem;
}

.single-content img {
    border-radius: 4px;
}

/* Images render at their own width rather than being shrunk to the 700px
   reading column, centred on the page and capped at the ceiling the featured
   image uses.

   margin-left:50% plus a half-width translate is what centres a box wider than
   its parent: margin:auto collapses to 0 once the child exceeds the container,
   so it cannot centre an overflowing image.

   The figure is given the full breakout width rather than being sized from its
   image. Intrinsic sizing was tried first and does not work here: the base
   img rule sets max-width:100%, and a percentage max-width makes the image
   contribute nothing to its parent's intrinsic width, so width:min-content
   collapsed the figure to 0. width:fit-content failed differently, clamping to
   the space left after margin-left:50% had taken half the column, giving 326px.
   A definite width avoids both traps. The image then sits at its own size
   inside that box, centred by auto margins, and the caption centres under it
   on the text-align rule the theme already applies to figcaption.

   Gated at 1140px to match .alignwide above: below that the column is already
   close to the viewport width, so there is nothing to break out of. Floats and
   the explicit wide/full alignments keep their own behaviour. */
@media (min-width: 1140px) {
    .single-content > figure:not(.alignleft):not(.alignright):not(.alignwide):not(.alignfull),
    .single-content > .wp-block-image:not(.alignleft):not(.alignright):not(.alignwide):not(.alignfull) {
        width: min(1400px, 100vw - 3rem);
        margin-left: 50%;
        transform: translateX(-50%);
    }

    .single-content > figure:not(.alignleft):not(.alignright):not(.alignwide):not(.alignfull) > img,
    .single-content > .wp-block-image:not(.alignleft):not(.alignright):not(.alignwide):not(.alignfull) > img {
        margin-left: auto;
        margin-right: auto;
    }

    .single-content > img:not(.alignleft):not(.alignright),
    .single-content > p > img:not(.alignleft):not(.alignright) {
        max-width: min(1400px, 100vw - 3rem);
        margin-left: 50%;
        transform: translateX(-50%);
    }
}

.single-content hr {
    border: 0;
    border-top: 1px solid var(--border);
    margin: 3rem 0;
}

.single-content table {
    border-collapse: collapse;
    margin-bottom: 1.5rem;
    width: 100%;
}

.single-content th,
.single-content td {
    border: 1px solid var(--border);
    padding: 0.6rem 0.8rem;
    text-align: left;
}

.single-content th {
    background: var(--bg-secondary);
    font-weight: 500;
}

.post-password-form input[type="password"] {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: inherit;
    margin-left: 0.5rem;
    padding: 0.5rem 0.8rem;
}

/* ========== COMMENTS ========== */
.comments-area {
    max-width: 700px;
    margin: 0 auto;
    padding: 0 1.5rem 4rem;
}

.comments-title {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--text-muted);
    font-weight: 400;
    margin-bottom: 2rem;
}

.comment-list {
    list-style: none;
    margin: 0 0 2.5rem;
    padding: 0;
}

.comment-list .children {
    list-style: none;
    margin: 1.5rem 0 0;
    padding-left: 1.5rem;
    border-left: 1px solid var(--border);
}

.comment-body {
    border-bottom: 1px solid var(--border);
    padding-bottom: 1.5rem;
    margin-bottom: 1.5rem;
}

.comment-meta {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.comment-author img {
    border-radius: 50%;
    display: inline-block;
}

.comment-metadata,
.comment-metadata a {
    color: var(--text-muted);
    font-size: 0.8rem;
}

.comment-content p {
    margin-bottom: 1rem;
}

.comment-respond {
    margin-top: 2.5rem;
}

.comment-reply-title {
    font-size: 1.1rem;
    font-weight: 400;
    margin-bottom: 1rem;
}

.comment-form label {
    color: var(--text-secondary);
    display: block;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.95rem;
    padding: 0.7rem 1rem;
    width: 100%;
}

.comment-form p {
    margin-bottom: 1.2rem;
}

.comment-form .submit {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-hover);
    border-radius: 4px;
    color: var(--text-primary);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    padding: 0.7rem 1.4rem;
    transition: color var(--transition), border-color var(--transition);
}

.comment-form .submit:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.no-comments {
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* ========== REDUCED MOTION ========== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
        transition-duration: 0.01ms !important;
    }

    .photo-card:hover img {
        transform: none;
    }
}

/* ========== RESPONSIVE ========== */
@media (max-width: 768px) {
    .site-title {
        font-size: 1.8rem;
    }

    .photo-grid {
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 1rem;
    }

    .text-post-item {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }

    .text-post-date {
        margin-left: 0;
    }

    .single-title {
        font-size: 1.5rem;
    }
}

@media (max-width: 480px) {
    .photo-grid {
        grid-template-columns: 1fr;
    }

    .site-nav a {
        margin: 0 0.5rem;
        font-size: 0.8rem;
    }
}
