/* eslint-disable */
/* Artifex Heritage — Home page (signature arrival) */

function HomeScreen() {
  const projects = window.AH_DATA.projects.slice(0, 4);
  const heroRef = React.useRef(null);
  const lineRef = React.useRef(null);
  const frameRef = React.useRef(null);

  React.useEffect(() => {
    const h1 = heroRef.current;
    const line = lineRef.current;
    const frame = frameRef.current;
    if (!h1 || !line || !frame) return;

    // Constant gap (px) between the deepest descender ink and the image top.
    const CLEARANCE = 8;
    const FLOOR = 56;   // headline never renders below this
    const CEIL = 240;   // …nor above this
    const BASE = 100;
    const measureCanvas = document.createElement("canvas").getContext("2d");

    // Single pass: size the line to the width between the equal margins
    // (clamped 56–240px, wrapping below the floor), then publish the
    // content-driven band height so the frame shrinks/grows with the headline
    // and the image follows it directly below — 8px under the descender ink.
    const fitAndPlace = () => {
      // --- 1. Fit width, then clamp ---
      // Available width = the h1's own content box, i.e. the span between the
      // equal left/right gutter margins (.ah-page has max-width:none — no cap).
      const available = h1.clientWidth;
      if (!available) return;
      // Measure the single-line text width at the BASE size.
      line.style.whiteSpace = "nowrap";
      h1.style.fontSize = BASE + "px";
      // The line is display:block (stretches to the container); shrink-wrap it
      // so scrollWidth reports the true text width, not the container width.
      const prevDisplay = line.style.display;
      line.style.display = "inline-block";
      const measured = line.scrollWidth;
      line.style.display = prevDisplay;
      if (!measured) return;

      const fillSize = BASE * available / measured; // fills width exactly
      let fontSize;
      if (fillSize >= FLOOR) {
        // Normal range and above: fill the width, but never exceed the ceiling.
        // Above the ceiling the line stops growing and the centred text leaves
        // equal margins that widen with the viewport.
        fontSize = Math.min(CEIL, fillSize);
        line.style.whiteSpace = "nowrap";
      } else {
        // Below the width at which a single line would dip under the floor:
        // hold at the floor and let the headline wrap to two lines.
        fontSize = FLOOR;
        line.style.whiteSpace = "normal";
      }
      h1.style.fontSize = fontSize + "px";

      // --- 2. Content-driven band = top gap + headline + 8px clearance ---
      // The headline is top-pinned by the frame's top padding (the locked
      // gap). The image sits directly below the band, CLEARANCE px under the
      // deepest descender ink. We publish the band height (frame height ==
      // image-descent / text-rise travel == rest-image crop) as one value.
      //
      // The line carries the rise animation's transform, which may be at any
      // phase right now. Read it and subtract so we measure the RESTING state.
      let lineTy = 0;
      try {
        lineTy = new DOMMatrixReadOnly(getComputedStyle(line).transform).m42 || 0;
      } catch (e) { lineTy = 0; }

      // Baseline Y of the rendered (last) line: an empty 0×0 inline-block
      // aligned to the baseline sits exactly on it.
      const probe = document.createElement("span");
      probe.style.cssText = "display:inline-block;width:0;height:0;vertical-align:baseline;";
      line.appendChild(probe);
      const baselineY = probe.getBoundingClientRect().top;
      line.removeChild(probe);

      // True glyph descent (ink below baseline) at the computed size — avoids
      // line-height padding inflating the gap. Fallback to the line-box bottom.
      let descent;
      measureCanvas.font = "500 " + fontSize + "px " + getComputedStyle(h1).fontFamily;
      const m = measureCanvas.measureText(line.textContent);
      if (m && m.actualBoundingBoxDescent) {
        descent = m.actualBoundingBoxDescent;
      } else {
        descent = line.getBoundingClientRect().bottom - baselineY;
      }

      // Resting descender ink bottom (animation offset stripped) and the frame's
      // (un-animated) top — both in viewport coords, so their difference is the
      // resting band height regardless of scroll position.
      const restDescenderBottom = baselineY + descent - lineTy;
      const frameTop = frame.getBoundingClientRect().top;
      const band = (restDescenderBottom + CLEARANCE) - frameTop;
      if (band > 0) {
        document.documentElement.style.setProperty("--ah-hero-band", band + "px");
      }
    };

    let raf = 0;
    const onResize = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => { raf = 0; fitAndPlace(); });
    };

    // Measure only after Tid Display has loaded, while the line is still
    // hidden (opacity 0, pre-rise), so it reveals already sized AND placed.
    let cancelled = false;
    (document.fonts && document.fonts.ready
      ? document.fonts.ready
      : Promise.resolve()
    ).then(() => { if (!cancelled) fitAndPlace(); });

    window.addEventListener("resize", onResize);
    return () => {
      cancelled = true;
      window.removeEventListener("resize", onResize);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <div data-screen-label="Home">
      <section className="ah-page">
        <div className="ah-hero" data-hero-rule="exempt">
          <div className="ah-hero-frame" ref={frameRef}>
            <h1
              ref={heroRef}
              className="ah-hero-build"
              aria-label="Heritage Carpentry & Joinery"
              style={{ fontWeight: "500" }}>
              <span className="ah-hero-build-row">
                <span ref={lineRef} className="ah-hero-build-line ah-hero-build-line--1">Heritage Carpentry &amp; Joinery</span>
              </span>
            </h1>
          </div>

          <div className="ah-hero-figure"><Img variant="oak" /></div>
        </div>
        <p className="ah-hero-dek ah-hero-dek--statement">Repair &amp; reproduction of historic woodwork.<br />Bespoke work &amp; heritage consultancy.</p>
      </section>

      <section className="ah-page">
        <div className="ah-hero-intro ah-hero-intro--columns ah-credo-spread">
          <div className="ah-intro-aside"></div>
          <div className="ah-prose ah-prose--news">
            <p className="ah-drop">
              Artifex Heritage is a heritage conservation firm in Ottawa &ndash; carpenters and joiners, consultants, and stewards to the Victorian, Edwardian, and ecclesiastical buildings of the capital and eastern Ontario. At the bench, the workshop repairs and remakes the woodwork older buildings live by, and takes new commissions in the same tradition: doors, windows, staircases, panelling, and mantels. At the desk, the practice advises the owners of historic houses, churches, and institutions: condition assessments, research, management plans, grants, and permits.
            </p>
          </div>
        </div>
      </section>

      <section className="ah-page">
        <div className="ah-work-head">
          <h2 className="ah-h2 ah-work-head__title">Selected Works</h2>
        </div>
        <div className="ah-grid-4 ah-grid-4--bleed">
          {projects.map((p) => <ProjectTile key={p.id} project={p} />)}
        </div>
      </section>

      <HeritageBand />

      <ServicesSection />

      <ServiceMap />

      <ProcessBand />

      {/* AFFILIATIONS SECTION. REMOVED FROM HOMEPAGE RENDER, PRESERVED FOR FUTURE REINSTATEMENT. DO NOT DELETE.
          The <AffiliationsBand /> render call was removed here for launch. The
          component itself (function AffiliationsBand) remains defined and intact
          below in this file, dormant. To reinstate, restore the line:
              <AffiliationsBand />
          at this position — nothing else needs rebuilding. */}

      <SealRow />
    </div>);

}

/* ----------------------------------------------------------------
   Process band — credo-and-paragraph block directly above the Services
   section. Same treatment as the Heritage credo band (Tid Display italic
   credo line over a single condensed Inter paragraph carrying the
   homepage's centred editorial rule, with an under-paragraph link). Links
   to the Working With Us / Process page at its current route.
   ---------------------------------------------------------------- */
function ProcessBand() {
  return (
    <section className="ah-process-band" aria-labelledby="ah-process-credo">
      <div className="ah-statement ah-statement--credo">
        <p className="ah-credo__line" id="ah-process-credo">First the reading, then the repair.</p>
        <div className="ah-hero-intro--columns ah-credo-spread">
          <div className="ah-intro-aside"></div>
          <div className="ah-prose ah-prose--news">
            <p>Every commission follows the same order of operations: an enquiry, a site visit, research before any proposal, work carried out to a written scope, and a record of what was done and why. The practice consults the archive as readily as the tool chest, from fire insurance plans to parish records to the evidence held in the fabric itself. The whole sequence is set out plainly, from first correspondence to final photograph.</p>
            <div className="ah-prose-linkrow">
              <a href="the-process.html" className="ah-tlink ah-intro-link">READ THE PROCESS</a>
            </div>
          </div>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------------
   Heritage band — full-bleed cream band directly after the Service
   Area section. Duplicates the Service Area credo band exactly (italic
   display line, offset justified paragraph with the centre hairline,
   small-caps text link bottom-right). Reuses the credo/statement classes
   verbatim; the only band-level rule is the cream chassis so it paints
   over the map section's -175px desktop overlap, mirroring .ah-affil.
   ---------------------------------------------------------------- */
function HeritageBand() {
  return (
    <section className="ah-heritage-band" aria-labelledby="ah-heritage-credo">
      <div className="ah-statement ah-statement--credo">
        <p className="ah-credo__line" id="ah-heritage-credo">Professionals who specialize in heritage conservation.</p>
        <div className="ah-hero-intro--columns ah-credo-spread">
          <div className="ah-intro-aside"></div>
          <div className="ah-prose ah-prose--news">
            <p>The Artifex Heritage team members have been trained at the nation&rsquo;s top institutions specializing in heritage trades and take pride in what they do. Algonquin College&rsquo;s Heritage Carpentry &amp; Joinery program is one of only two college programs in Canada devoted to heritage carpentry. Willowbank School of Restoration Arts is the only school of its kind in the country, being the Canadian headquarters of the International Network for Traditional Building, Architecture &amp; Urbanism (INTBAU), and one of a handful of Canadian institutions under the Royal Patronage of His Majesty King Charles III.</p>
            <div className="ah-prose-linkrow">
              <a href="about.html" className="ah-tlink ah-intro-link">READ ARTIFEX HERITAGE</a>
            </div>
          </div>
        </div>
      </div>
    </section>);

}

/* ----------------------------------------------------------------
   AFFILIATIONS SECTION. REMOVED FROM HOMEPAGE RENDER, PRESERVED FOR FUTURE REINSTATEMENT. DO NOT DELETE.
   Affiliations — full-bleed brown band, editorial hero + slow marquee.
   Sat directly above the footer on the homepage. The component and its
   styles (.ah-affil* in site.css) are fully intact; it is simply no
   longer rendered (its <AffiliationsBand /> call was removed from
   HomeScreen). Re-add that one line to reinstate.
   ---------------------------------------------------------------- */
function AffiliationsBand() {
  const items = [
    'Algonquin College',
    'Willowbank School of Restoration Arts',
    'Christ the Saviour Orthodox Church',
    'Saint Clement Parish',
    'Tower of Ivory Studios',
    'Assumption of the Blessed Virgin Ukrainian Orthodox Cathedral'];

  // Names that wrap to two lines, broken exactly at the given seam.
  const stacked = {
    'Willowbank School of Restoration Arts': ['Willowbank School', 'of Restoration Arts'],
    'Christ the Saviour Orthodox Church': ['Christ the Saviour', 'Orthodox Church'],
    'Assumption of the Blessed Virgin Ukrainian Orthodox Cathedral': ['Assumption of the Blessed Virgin', 'Ukrainian Orthodox Cathedral']};


  return (
    <section className="ah-affil" aria-labelledby="ah-affil-title">
      <div className="ah-affil-hero">
        <h2 id="ah-affil-title" className="ah-affil-hero__title">Affiliations</h2>
      </div>

      {/* Visually-hidden accessible list */}
      <ul className="ah-sr-only">
        {items.map((name) => <li key={name}>{name}</li>)}
      </ul>

      {/* Marquee row — flex-centred between the rule above (rendered as
          border-top on this wrap, matching the footer's border-top
          implementation exactly) and the footer's own top border below. */}
      <div className="ah-affil-marquee-wrap">
        <div className="ah-affil-marquee" aria-hidden="true">
          <div className="ah-affil-marquee__track">
            {[0, 1].map((rep) =>
            <div className="ah-affil-marquee__set" key={rep}>
                {items.map((name, i) => {
              const parts = stacked[name];
              return (
                <span
                  className={'ah-affil-mark' + (parts ? ' ah-affil-mark--stack' : '')}
                  key={`${rep}-${i}`}>
                {parts ?
                <React.Fragment>
                      <span className="ah-affil-mark__line">{parts[0]}</span>
                      <span className="ah-affil-mark__line">{parts[1]}</span>
                    </React.Fragment> :
                name}
                </span>);

            })}
              </div>
            )}
          </div>
        </div>
      </div>
    </section>);

}

/* Letter-by-letter arrival */
function HeroLetters({ text, delay = 0, italic }) {
  return (
    <span className={'ah-hero-letters' + (italic ? ' is-italic' : '')}>
      {text.split('').map((ch, i) =>
      <span
        key={i}
        className="ah-letter"
        style={{ animationDelay: `${delay + i * 55}ms` }}>
        {ch === ' ' ? '\u00A0' : ch}</span>
      )}
    </span>);

}

window.HomeScreen = HomeScreen;
window.HeroLetters = HeroLetters;
window.HeritageBand = HeritageBand;
window.ProcessBand = ProcessBand;
window.AffiliationsBand = AffiliationsBand;

/* ----------------------------------------------------------------
   Services — homepage section directly above Service Area. A single
   100px "Services" display heading, an info block that names one of
   five categories and lists its services, and a row of five portrait
   placeholder plates. One plate is always selected (full colour);
   the rest are greyscale. Hovering any greyscale plate brings it to
   colour for the hover's duration and swaps the info block to that
   category; clicking makes it the new selected plate. All swaps are
   instant — no transition, per the house rule. Desktop pass only.
   ---------------------------------------------------------------- */
function ServicesSection() {
  const SERVICES = [
    { num: '01', name: 'Windows', variant: 'oak', items: ['Sashes', 'Casements', 'Reglazing'] },
    { num: '02', name: 'Doors', variant: 'pine', items: ['Interior Doors', 'Exterior Doors'] },
    { num: '03', name: 'Interiors', variant: 'sand', items: ['Panelling', 'Flooring', 'Mantels', 'Staircases'] },
    { num: '04', name: 'Bespoke', variant: 'brass', items: ['Commissioned Design', 'Custom Build'] },
    { num: '05', name: 'Consultancy', variant: 'sage', items: ['Assessment', 'Research', 'Advisory'] }];


  const [selected, setSelected] = React.useState(0);
  const [hovered, setHovered] = React.useState(null);
  const shown = hovered != null ? hovered : selected;
  const cat = SERVICES[shown];

  return (
    <section className="ah-page">
      <div className="ah-services">
        <h2 className="ah-services__title">Services</h2>

        <div className="ah-services__info">
          <span className="ah-services__rule" aria-hidden="true"></span>
          <p className="ah-services__cat">{cat.num}. {cat.name}</p>
          <ul className="ah-services__list">
            {cat.items.map((it) => <li key={it}>{it}</li>)}
          </ul>
        </div>

        <div className="ah-services__row">
          {SERVICES.map((s, i) => {
            const colour = i === selected || i === hovered;
            return (
              <figure className="ah-services__cell" key={s.num}>
                <span className="ah-services__label">/ {s.num}</span>
                <div
                  className="ah-services__plate"
                  data-colour={colour ? 'true' : 'false'}
                  onMouseEnter={() => setHovered(i)}
                  onMouseLeave={() => setHovered(null)}
                  onClick={() => setSelected(i)}>
                  <Img variant={s.variant} />
                </div>
              </figure>);

          })}
        </div>
      </div>
    </section>);

}

window.ServicesSection = ServicesSection;