/* ─────────────────────────────────────────────────────────────
   Single project
   ───────────────────────────────────────────────────────────── */

/* ─── Hero ─────────────────────────────────────────────────
   Full-bleed photograph, title set low-left rather than floating
   dead-centre. The centred treatment read as a stock template and
   collapsed badly on a phone, where a wide crop leaves the title
   stranded in a thin letterbox.                                  */
.jm-project__hero {
    position: relative;
    min-height: clamp(420px, 68vh, 760px);
    display: flex;
    align-items: flex-end;
    background: var(--primary-dark);
    overflow: hidden;
}

.jm-project__hero-media {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.jm-project__hero-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.06);
    /* A very slow drift. Long and small enough to register as depth
       rather than as movement. */
    animation: jm-kenburns 26s var(--ease) forwards;
}

@keyframes jm-kenburns {
    from { transform: scale(1.12); }
    to   { transform: scale(1.0); }
}

/* Gradient weighted to the bottom, where the type sits, so the top of
   the photograph stays clean. */
.jm-project__hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(to bottom,
            rgba(18, 28, 33, 0.28) 0%,
            rgba(18, 28, 33, 0.10) 32%,
            rgba(18, 28, 33, 0.55) 74%,
            rgba(18, 28, 33, 0.86) 100%);
}

.jm-project__hero-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    padding-bottom: clamp(40px, 7vw, 84px);
    padding-top: clamp(80px, 14vw, 160px);
}

.jm-project__eyebrow {
    color: rgba(255, 255, 255, 0.78);
    font-size: var(--fs-eyebrow);
    font-weight: 600;
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    text-indent: var(--ls-eyebrow);
    margin: 0 0 var(--sp-4);
    /* a short rule before the label, the architectural tell */
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

.jm-project__eyebrow::before {
    content: "";
    width: 34px;
    height: 1px;
    background: rgba(255, 255, 255, 0.6);
    flex: none;
}

.jm-project__title {
    color: #fff;
    font-size: var(--fs-display);
    font-weight: 300;
    line-height: 1.04;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    margin: 0;
    max-width: 16ch;
}

.jm-project__subtitle {
    color: rgba(255, 255, 255, 0.86);
    font-size: var(--fs-h3);
    font-weight: 300;
    line-height: 1.45;
    margin: var(--sp-4) 0 0;
    max-width: 44ch;
}

/* Entrance: eyebrow, title and standfirst rise in sequence. */
.jm-project__eyebrow,
.jm-project__title,
.jm-project__subtitle {
    animation: jm-rise 0.9s var(--ease) both;
}
.jm-project__eyebrow  { animation-delay: 0.05s; }
.jm-project__title    { animation-delay: 0.15s; }
.jm-project__subtitle { animation-delay: 0.28s; }

@keyframes jm-rise {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
}

/* ─── Scroll cue ───────────────────────────────────────────── */
.jm-project__scroll {
    position: absolute;
    right: clamp(20px, 4vw, 48px);
    bottom: clamp(28px, 5vw, 56px);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    color: rgba(255, 255, 255, 0.82);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    text-decoration: none;
    writing-mode: vertical-rl;
}

.jm-project__scroll svg {
    writing-mode: horizontal-tb;
    animation: jm-nudge 2.4s var(--ease) infinite;
}

@keyframes jm-nudge {
    0%, 100% { transform: translateY(0); opacity: 0.85; }
    50%      { transform: translateY(5px); opacity: 1; }
}

@media (hover: hover) and (pointer: fine) {
    .jm-project__scroll:hover { color: #fff; }
}

@media (max-width: 700px) {
    /* A phone screen is portrait; a wide letterbox wastes it and squeezes
       the title. Give the hero real height and drop the vertical cue. */
    .jm-project__hero { min-height: 74vh; }
    .jm-project__title { max-width: 12ch; }
    .jm-project__scroll { display: none; }
}

/* ─── Spec bar ───────────────────────────────────────────────
   The facts, set as a quiet row rather than four bordered boxes. The
   boxed version fell apart on a phone: two ragged columns of unequal
   height with rules cutting between them. Here each item is just a
   label over a value, with a single accent tick to anchor it.        */
.jm-project__specs {
    /* Lifts over the bottom of the photograph — the card-over-image move
       that ties the two together instead of stacking them as strips. */
    position: relative;
    z-index: 2;
    margin-top: clamp(-40px, -4vw, -28px);
    padding: 0 clamp(10px, 2.2vw, 26px);
}

.jm-project__specs .jm-panel {
    padding: clamp(22px, 3vw, 34px) clamp(20px, 3vw, 36px);
}

.jm-specs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(20px, 3vw, 40px) clamp(18px, 3vw, 36px);
    margin: 0;
}

@media (min-width: 820px) {
    .jm-specs { grid-template-columns: repeat(4, 1fr); }
}

.jm-specs__item {
    position: relative;
    padding-left: var(--sp-4);
}

/* A short accent tick instead of a full box. */
.jm-specs__item::before {
    content: "";
    position: absolute;
    left: 0;
    top: 3px;
    bottom: 3px;
    width: 2px;
    background: var(--accent);
    opacity: 0.55;
}

.jm-specs__label {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--text-light);
    margin: 0 0 6px;
}

.jm-specs__value {
    margin: 0;
    font-size: var(--fs-body);
    line-height: 1.45;
    color: var(--text-primary);
    font-weight: 600;
}

/* ─── Body ─────────────────────────────────────────────────── */
/* Body copy sits directly on the page. Panelling it boxed the reading
   column in twice over — the panel's padding plus the measure — and
   pushed the text away from the edges on a phone, where the screen is
   already narrow. The photographs keep their mounts; the words do not. */
.jm-project__body {
    padding: clamp(28px, 4vw, 56px) clamp(16px, 4vw, 24px) 0;
}

.jm-project__sheet {
    max-width: 1000px;
    margin-inline: auto;
}

.jm-project__content { max-width: 68ch; margin-inline: auto; }

.jm-project__content h2 {
    font-size: var(--fs-h2);
    margin-top: var(--sp-7);
}

.jm-project__content h3 {
    font-size: var(--fs-h3);
    color: var(--primary);
    margin-top: var(--sp-6);
}

.jm-project__content > *:first-child { margin-top: 0; }

.jm-project__content p { color: var(--text-secondary); }

.jm-project__content ul {
    margin: 0 0 var(--sp-4);
    padding-left: 0;
    list-style: none;
}

.jm-project__content li {
    position: relative;
    padding-left: var(--sp-5);
    margin-bottom: var(--sp-2);
    color: var(--text-secondary);
}

/* A small square marker rather than a bullet — squarer, more architectural. */
.jm-project__content li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 6px;
    height: 6px;
    background: var(--primary);
}

/* Photographs are mounted: the panel treatment reduced to a frame, and
   set wider than the reading column so the images carry the page while
   the text stays at a comfortable measure. */
.jm-project__content figure.wp-block-image {
    margin: clamp(28px, 4vw, 52px) 0;
    width: 100%;
    background: var(--bg-white);
    border: 1px solid rgba(104, 152, 168, 0.20);
    border-radius: 16px;
    padding: 7px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.7),
        0 22px 44px -28px rgba(22, 40, 48, 0.5);
    cursor: zoom-in;
    transition: box-shadow 0.4s var(--ease), transform 0.4s var(--ease);
}

@media (min-width: 860px) {
    .jm-project__content figure.wp-block-image {
        width: calc(100% + clamp(40px, 7vw, 120px));
        margin-left: calc(clamp(40px, 7vw, 120px) / -2);
    }
}

@media (hover: hover) and (pointer: fine) {
    .jm-project__content figure.wp-block-image:hover {
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.7),
            0 26px 52px -26px rgba(22, 40, 48, 0.58);
        transform: translateY(-2px);
    }
}

.jm-project__content figure.wp-block-image img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 10px;
}

/* ─── Location ───────────────────────────────────────────────
   The map itself is blocks/page/map/, shared with the contact page.
   Only the section's own spacing lives here.                      */
.jm-project__location { padding: 0; }

/* ─── Back ─────────────────────────────────────────────────── */
.jm-project__back {
    padding: clamp(40px, 6vw, 72px) 0;
    text-align: center;
    background: var(--bg-white);
}


/* ─── Panel rhythm ───────────────────────────────────────────
   Every panel on the page shares one inset and one gap, so the stack
   reads as a deliberate sequence rather than sections that happen to
   touch the screen edges at different points.

   The map belongs to this stack too, but it carries the same inset and gap
   itself — see blocks/page/map — because the contact page uses it and has no
   panel rhythm of its own to inherit. */
.jm-floorplans,
.jm-gallery-section {
    margin-inline: clamp(12px, 2.4vw, 28px);
    margin-top: clamp(16px, 2.4vw, 30px);
}

.jm-floorplans {
    border-radius: 20px;
    border: 1px solid rgba(104, 152, 168, 0.22);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.65),
        0 20px 46px -30px rgba(22, 40, 48, 0.45);
}

/* The panel already carries the inset, so its inner container must not
   add its own gutter on top. */
.jm-gallery-section > .jm-panel,
.jm-project__location > .jm-panel {
    width: 100%;
    max-width: none;
    margin-inline: 0;
}

.jm-project__back { padding: clamp(32px, 4.5vw, 56px) 0; }
