/**
 * Frontier Valley — a startup in a hangar at Alameda Point.
 *
 * The second office pack, and it exists to prove the format describes more than
 * one kind of building. `lumbridge-hq.ts` is the dev kit: a corridor, fifteen
 * rooms, a grid, everything a commercial floor plate has. This is the opposite
 * building in every respect that matters, and the contrast is the point.
 *
 * ### Why a hangar, and why here
 *
 * Alameda Point is the former Naval Air Station Alameda, decommissioned in 1997:
 * a mile of runway, a seaplane lagoon, and a row of enormous steel-framed
 * hangars that have spent the last quarter century being rented to distilleries,
 * film crews and companies that need a very large room cheaply. Putting a
 * startup in one is not a conceit — it is the single most characteristic thing
 * that happens on that piece of land.
 *
 * It also gives the site field something to say. `lumbridge-hq` is 188 m up a
 * tower with the horizon far below it; this is **four metres above reclaimed
 * ground on a flat island**, looking across the estuary at the city that the
 * other office is inside. Same engine, same clock, same sun — and the two feel
 * nothing like each other, which is the whole argument for `OfficeSite`.
 *
 * ### One level, one room, and a mezzanine that is furniture
 *
 * A hangar is a single volume. There is no corridor here because there is
 * nothing to connect: the meeting rooms are freestanding boxes dropped on the
 * slab, with their own low lids, and everything else is open floor. That is
 * expressible in this format without a single new feature, which is worth
 * knowing — the format was written against a cellular office and turns out to
 * describe a shed just as well.
 *
 * ### The coordinate frame
 *
 * Metres, `1 unit = 1 m`, floor on the XZ plane with +Y up. Origin at the
 * north-west corner. +X east, +Z south, so in plan view +Z runs down the page.
 * The one difference from the reference pack is that here "north" is a genuine
 * claim: `site.heading` is 0, because the hangars at Alameda Point really are
 * laid out square to the compass along the old runways.
 */

import type {
  AssetId,
  DeskBank,
  Level,
  Office,
  Opening,
  Outline,
  Point2,
  Prop,
  Room,
  Seat,
  Viewpoint,
  Wall,
  Yaw,
  Zone,
} from "../interiors/types.ts";
import { FRONTIER_VALLEY_SITE } from "./sites.ts";

// ---- The shed -------------------------------------------------------------

/**
 * A hangar, in three numbers.
 *
 * 54 x 30 m is a small one by Alameda standards — the surviving hangars on the
 * seaplane lagoon run to twice this — but it is a plausible sublet, and it is
 * already three times the floor area of the reference office's desk floor with
 * nothing standing in it.
 */
const WIDTH = 54.0;
const DEPTH = 30.0;

/**
 * Nine metres to the underside of the trusses.
 *
 * This is the number that makes it a hangar rather than a warehouse-themed
 * office. A commercial storey is 2.8 m; at 9 m the roof is somewhere you look
 * *up* at, the meeting boxes read as objects standing in a room rather than as
 * rooms carved out of one, and a mezzanine is a thing you can put under it.
 */
const RIDGE = 9.0;

/** The freestanding boxes get their own low lids. A booth in a shed is a box. */
const BOX_CEILING = 3.0;

const EXT_THICKNESS = 0.35;
const INT_THICKNESS = 0.12;
const EXT_FACE = EXT_THICKNESS / 2;
const INT_FACE = INT_THICKNESS / 2;

const DISPLAY_OFFSET = 0.07;
const BOARD_OFFSET = 0.06;

/**
 * The mezzanine deck.
 *
 * It is a `Level`, and getting there took one wrong turn worth recording. A deck
 * inside a single volume reads like furniture, so it was first authored as a
 * `Room` on the ground floor with everything on it carrying `elevation: 4.4`.
 * That is not expressible: a `Room` is a floor *finish* and has no height, so
 * the deck's slab lay flat on the concrete while its chairs floated four and a
 * half metres over it, its glass balustrade fenced off a patch of ground-floor
 * slab, and anybody sitting at `mezz-01` stood on the concrete underneath their
 * own chair.
 *
 * A `Level` is the only thing in this format that carries a floor height, so the
 * deck is one — with a storey height of `RIDGE - MEZZ_HEIGHT`, because what is
 * above it is the same roof.
 */
const MEZZ_W = 38.0;
const MEZZ_N = 20.4;
const MEZZ_HEIGHT = 4.4;

// The three freestanding boxes along the west end.
const BOX_1_W = 3.0;
const BOX_1_E = 10.2;
const BOX_2_W = 11.4;
const BOX_2_E = 17.4;
const BOX_N = 3.0;
const BOX_S = 9.6;

// ---- Yaw ------------------------------------------------------------------

const NORTH: Yaw = 0;
const EAST: Yaw = -Math.PI / 2;
const SOUTH: Yaw = Math.PI;
const WEST: Yaw = Math.PI / 2;

// ---- Assets ---------------------------------------------------------------

const DESK: AssetId = "tera:desk.workstation";
const PEDESTAL: AssetId = "tera:desk.pedestal";
const TASK_CHAIR: AssetId = "tera:seat.task-chair";
const LOUNGE_CHAIR: AssetId = "tera:seat.lounge";
const MEETING_TABLE: AssetId = "tera:table.meeting";
const SIDE_TABLE: AssetId = "tera:table.side";
const SHELF: AssetId = "tera:storage.shelf";
const LOCKER: AssetId = "tera:storage.locker";
const DISPLAY: AssetId = "tera:screen.wall-display";
const PLANT: AssetId = "tera:plant.potted";
const TREE: AssetId = "tera:plant.tall";
const PENDANT: AssetId = "tera:light.pendant";
const RUG: AssetId = "tera:rug";
const WHITEBOARD: AssetId = "tera:whiteboard";

const CONCRETE = "tera:concrete.polished";
const WOOD = "tera:wood.plank";
const CARPET_ACCENT = "tera:carpetAccent.broadloom";
const PAINT = "tera:paint.matt";
const ACCENT_PAINT = "tera:plasterAccent.deep";
const GLASS = "tera:glass.curtain";
const STEEL = "tera:steel.panel";
const FELT = "tera:felt.acoustic";

// ---- Helpers --------------------------------------------------------------

function rect(x0: number, z0: number, x1: number, z1: number): Outline {
  return [
    { x: x0, z: z0 },
    { x: x0, z: z1 },
    { x: x1, z: z1 },
    { x: x1, z: z0 },
  ];
}

function grid(x0: number, z0: number, columns: number, rows: number, dx: number, dz: number): Point2[] {
  const points: Point2[] = [];
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < columns; c++) points.push({ x: x0 + c * dx, z: z0 + r * dz });
  }
  return points;
}

function scatter(
  prefix: string,
  kind: AssetId,
  points: Point2[],
  opts: { rotation?: Yaw; elevation?: number; colorKey?: string } = {},
): Prop[] {
  return points.map((position, i) => ({
    id: `${prefix}-${String(i + 1).padStart(2, "0")}`,
    kind,
    position,
    rotation: opts.rotation ?? NORTH,
    // Spread rather than assigned, because `elevation: undefined` is not the
    // same shape as no `elevation` at all: `JSON.stringify` drops the key and a
    // pack that has been through the wire stops deep-equalling the one in the
    // bundle. CONTRACT.md §2 says those two have to be literally the same
    // thing, and `src/test/packs/packRegression.test.ts` now checks it.
    ...(opts.elevation === undefined ? {} : { elevation: opts.elevation }),
    ...(opts.colorKey === undefined ? {} : { colorKey: opts.colorKey }),
  }));
}

function doorway(start: number, width = 0.9, head = 2.1): Opening {
  return { kind: "door", start, width, sill: 0, head };
}

function pane(start: number, width: number, sill = 0.9, head = 2.2): Opening {
  return { kind: "window", start, width, sill, head };
}

function archway(start: number, width: number, head = 2.4): Opening {
  return { kind: "arch", start, width, sill: 0, head };
}

// ---- Rooms ----------------------------------------------------------------

const ROOMS: Room[] = [
  /**
   * The slab. One room, fifty-four by thirty, notched around nothing.
   *
   * Every other "room" in this pack sits on top of this one as a different floor
   * finish, and they are authored *after* it so `Plan.roomAt` resolves them
   * first. That is the one ordering rule in the format and it is doing real work
   * here: in the reference office the floor is a jigsaw of abutting slabs, and
   * here it is one slab with rugs on it.
   */
  {
    id: "floor",
    name: "The Floor",
    outline: rect(0, 0, WIDTH, DEPTH),
    floor: CONCRETE,
    ceiling: null,
  },
  {
    id: "box-standup",
    name: "Standup",
    outline: rect(BOX_1_W, BOX_N, BOX_1_E, BOX_S),
    floor: CARPET_ACCENT,
    ceiling: { height: BOX_CEILING, surface: FELT },
  },
  {
    id: "box-quiet",
    name: "The Quiet Box",
    outline: rect(BOX_2_W, BOX_N, BOX_2_E, BOX_S),
    floor: CARPET_ACCENT,
    ceiling: { height: BOX_CEILING, surface: FELT },
  },
  {
    id: "workshop",
    name: "The Bench",
    // Against the east gable, where the big door is. A hardware startup in a
    // hangar puts the thing it is building next to the way out.
    outline: rect(42.0, 3.0, WIDTH - 0.4, 16.0),
    floor: CONCRETE,
    ceiling: null,
  },
  {
    id: "galley",
    name: "The Galley",
    outline: rect(3.0, 22.0, 16.0, DEPTH - 0.4),
    floor: WOOD,
    ceiling: null,
  },
];

// ---- Walls ----------------------------------------------------------------

const WALLS: Wall[] = [
  // -- The envelope, nine metres of it --------------------------------------
  {
    id: "gable-west",
    from: { x: 0, z: 0 },
    to: { x: 0, z: DEPTH },
    thickness: EXT_THICKNESS,
    height: RIDGE,
    surface: STEEL,
    openings: [doorway(13.6, 1.8, 2.4), pane(4.0, 6.0, 3.6, 7.2), pane(19.0, 6.0, 3.6, 7.2)],
  },
  {
    id: "gable-east",
    from: { x: WIDTH, z: 0 },
    to: { x: WIDTH, z: DEPTH },
    thickness: EXT_THICKNESS,
    height: RIDGE,
    surface: STEEL,
    // The hangar door. Twelve metres of it, full height, because that is what a
    // hangar is — and it is an `arch` rather than a `door` so the collider
    // knows you can walk out onto the apron through it.
    openings: [archway(6.0, 12.0, 6.4)],
  },
  {
    id: "eave-north",
    from: { x: 0, z: 0 },
    to: { x: WIDTH, z: 0 },
    thickness: EXT_THICKNESS,
    height: RIDGE,
    surface: STEEL,
    // Clerestory glazing high on the north side: the light a shed actually
    // wants, and the sill is well above head height so none of it is a doorway.
    openings: [
      pane(4.0, 9.0, 5.4, 8.2),
      pane(16.0, 9.0, 5.4, 8.2),
      pane(28.0, 9.0, 5.4, 8.2),
      pane(40.0, 9.0, 5.4, 8.2),
    ],
  },
  {
    id: "eave-south",
    from: { x: 0, z: DEPTH },
    to: { x: WIDTH, z: DEPTH },
    thickness: EXT_THICKNESS,
    height: RIDGE,
    surface: STEEL,
    // The lagoon side, and the only wall with glazing you can see out of at
    // standing height. This is the view the whole building is arranged around.
    openings: [
      pane(3.0, 10.0, 0.9, 3.4),
      pane(16.0, 10.0, 0.9, 3.4),
      pane(30.0, 8.0, 0.9, 3.4),
      doorway(44.0, 1.8, 2.4),
    ],
  },

  // -- The freestanding boxes -----------------------------------------------
  //
  // Three metres tall inside a nine-metre volume, which is what makes them read
  // as objects on the floor. Their fourth sides are open — a box you can see
  // into is a box people use.
  {
    id: "standup-north",
    from: { x: BOX_1_W, z: BOX_N },
    to: { x: BOX_1_E, z: BOX_N },
    height: BOX_CEILING,
    surface: ACCENT_PAINT,
  },
  {
    id: "standup-west",
    from: { x: BOX_1_W, z: BOX_N },
    to: { x: BOX_1_W, z: BOX_S },
    height: BOX_CEILING,
    surface: ACCENT_PAINT,
  },
  {
    id: "standup-south",
    from: { x: BOX_1_W, z: BOX_S },
    to: { x: BOX_1_E, z: BOX_S },
    height: BOX_CEILING,
    surface: GLASS,
    openings: [archway(2.4, 2.4, 2.4)],
  },
  {
    id: "quiet-north",
    from: { x: BOX_2_W, z: BOX_N },
    to: { x: BOX_2_E, z: BOX_N },
    height: BOX_CEILING,
    surface: ACCENT_PAINT,
  },
  {
    id: "quiet-east",
    from: { x: BOX_2_E, z: BOX_N },
    to: { x: BOX_2_E, z: BOX_S },
    height: BOX_CEILING,
    surface: ACCENT_PAINT,
  },
  {
    id: "quiet-south",
    from: { x: BOX_2_W, z: BOX_S },
    to: { x: BOX_2_E, z: BOX_S },
    height: BOX_CEILING,
    surface: GLASS,
    openings: [doorway(2.6, 0.9, 2.1)],
  },

];

// ---- Desks ----------------------------------------------------------------

/**
 * Two long benches down the middle of the shed, and nothing against a wall.
 *
 * A hangar's walls are its least valuable surface — they are steel, they are
 * cold, and the good light comes from above. So the desks sit in the volume and
 * the edges are left for the things that want an edge.
 */
const DESK_BANKS: DeskBank[] = [
  {
    id: "fv",
    desk: DESK,
    chair: TASK_CHAIR,
    origin: { x: 22.0, z: 5.2 },
    rotation: 0,
    columns: 7,
    rows: 2,
    pitch: 1.7,
    rowPitch: 0.85,
    facingRows: true,
  },
  {
    id: "fv-b",
    desk: DESK,
    chair: TASK_CHAIR,
    origin: { x: 22.0, z: 10.4 },
    rotation: 0,
    columns: 7,
    rows: 2,
    pitch: 1.7,
    rowPitch: 0.85,
    facingRows: true,
    seatPrefix: "fv-b",
  },
];

const SEATS: Seat[] = [
  { id: "standup-01", position: { x: 5.0, z: 5.6 }, facing: EAST, pose: "stand" },
  { id: "standup-02", position: { x: 8.2, z: 5.6 }, facing: WEST, pose: "stand" },
  { id: "standup-03", position: { x: 6.6, z: 4.4 }, facing: SOUTH, pose: "stand" },

  { id: "quietbox-01", position: { x: 13.0, z: 5.4 }, facing: EAST, pose: "sit" },
  { id: "quietbox-02", position: { x: 15.8, z: 5.4 }, facing: WEST, pose: "sit" },

  { id: "galley-01", position: { x: 6.0, z: 25.0 }, facing: SOUTH, pose: "stand" },
  { id: "galley-02", position: { x: 7.6, z: 25.0 }, facing: SOUTH, pose: "stand" },
  { id: "galley-03", position: { x: 9.2, z: 25.0 }, facing: SOUTH, pose: "stand" },
  // On the table's south long side, not on the tabletop: the table is centred on
  // z 27.0 and is 1.2 m deep, so a seat at 27.0 was inside it.
  { id: "galley-04", position: { x: 12.4, z: 28.0 }, facing: NORTH, pose: "sit" },
  { id: "galley-05", position: { x: 14.0, z: 28.0 }, facing: NORTH, pose: "sit" },

  { id: "bench-01", position: { x: 44.4, z: 6.0 }, facing: EAST, pose: "stand" },
  { id: "bench-02", position: { x: 44.4, z: 8.4 }, facing: EAST, pose: "stand" },
  { id: "bench-03", position: { x: 44.4, z: 10.8 }, facing: EAST, pose: "stand" },

];

// ---- Props ----------------------------------------------------------------

const PROPS: Prop[] = [
  // -- The desk floor -------------------------------------------------------
  ...scatter("fv-ped", PEDESTAL, grid(22.0, 6.8, 7, 1, 1.7, 0)),
  ...scatter("fv-ped-b", PEDESTAL, grid(22.0, 12.0, 7, 1, 1.7, 0)),
  /**
   * The lights, hung from the trusses at seven metres.
   *
   * The one place this pack really needs the ceiling-fixture exception: a
   * pendant is authored with its origin at the mounting plane and its geometry
   * below, so 7.2 is a real height in a 9 m shed and not an offset from a lid
   * that does not exist.
   */
  ...scatter("truss-light", PENDANT, grid(8.0, 5.0, 6, 4, 9.0, 7.0), { elevation: 7.2 }),

  // -- The boxes ------------------------------------------------------------
  { id: "standup-board", kind: WHITEBOARD, position: { x: 6.6, z: BOX_N + INT_FACE + BOARD_OFFSET }, rotation: NORTH, elevation: 1.0 },
  { id: "standup-rug", kind: RUG, position: { x: 6.6, z: 6.3 }, rotation: NORTH, colorKey: "team" },
  { id: "quiet-table", kind: MEETING_TABLE, position: { x: 14.4, z: 5.4 }, rotation: NORTH },
  ...scatter("quiet-chair", TASK_CHAIR, [
    { x: 13.0, z: 5.4 },
    { x: 15.8, z: 5.4 },
  ]),
  { id: "quiet-display", kind: DISPLAY, position: { x: 14.4, z: BOX_N + INT_FACE + DISPLAY_OFFSET }, rotation: NORTH, elevation: 1.15 },

  // -- The bench ------------------------------------------------------------
  // Four, starting at z 1.1: the gable is solid only for z 0..6, and the hangar
  // door's arch runs from 6.0 to 18.0 — a five-shelf run from 4.0 put three of
  // them standing in the open doorway.
  ...scatter("bench-shelf", SHELF, grid(WIDTH - EXT_FACE - 0.2, 1.1, 1, 4, 0, 1.2), { rotation: EAST }),
  { id: "bench-board", kind: WHITEBOARD, position: { x: 43.0, z: 3.0 + BOARD_OFFSET }, rotation: NORTH, elevation: 1.0 },
  ...scatter("bench-locker", LOCKER, grid(42.4, 13.0, 3, 1, 1.1, 0), { rotation: WEST }),

  // -- The galley -----------------------------------------------------------
  { id: "galley-rug", kind: RUG, position: { x: 9.0, z: 26.4 }, rotation: NORTH, colorKey: "social" },
  { id: "galley-table", kind: MEETING_TABLE, position: { x: 13.2, z: 27.0 }, rotation: NORTH },
  ...scatter("galley-lounge", LOUNGE_CHAIR, [
    { x: 6.0, z: 26.8 },
    { x: 8.4, z: 26.8 },
    { x: 10.8, z: 26.8 },
  ]),
  { id: "galley-side", kind: SIDE_TABLE, position: { x: 7.2, z: 25.8 }, rotation: NORTH },
  ...scatter("galley-plant", TREE, [
    { x: 4.0, z: 23.4 },
    { x: 15.0, z: 23.4 },
  ]),

  // -- The floor, kept mostly empty -----------------------------------------
  //
  // Three trees and nothing else. The shed's argument is the volume, and a
  // fifty-four-metre room with forty objects in it is a fifty-four-metre room
  // you cannot see across.
  ...scatter("floor-tree", TREE, [
    { x: 20.0, z: 20.0 },
    { x: 30.0, z: 24.0 },
    { x: 36.0, z: 4.0 },
  ]),
  ...scatter("floor-plant", PLANT, [
    { x: 19.6, z: 3.2 },
    { x: 34.0, z: 14.0 },
  ]),

];

// ---- Zones ----------------------------------------------------------------

const ZONES: Zone[] = [
  { id: "zone-build", name: "Build", outline: rect(42.0, 3.0, WIDTH - 0.4, 16.0), colorKey: "team" },
  { id: "zone-galley", name: "Galley", outline: rect(3.0, 22.0, 16.0, DEPTH - 0.4), colorKey: "social" },
];

// ---- Viewpoints -----------------------------------------------------------

const VIEWPOINTS: Viewpoint[] = [
  {
    id: "hangar",
    number: "01",
    label: "The Hangar",
    shortLabel: "Hangar",
    levelId: "level-1",
    focus: { at: { x: 27, z: 15 }, distance: 52, height: 26, rotation: 0.6 },
    description:
      "Fifty-four metres by thirty, nine to the trusses, one room. Everything Frontier Valley has is on this slab or on the deck at the far end.",
  },
  {
    id: "benches",
    number: "02",
    label: "The Benches",
    shortLabel: "Benches",
    levelId: "level-1",
    focus: { at: { x: 27.4, z: 8.0 }, distance: 15, height: 4.6, rotation: 0.4 },
    description:
      "Twenty-eight seats in two runs down the middle of the floor, under the trusses. Nothing is against a wall — in a shed the walls are the worst surface in the building.",
  },
  {
    id: "big-door",
    number: "03",
    label: "The Big Door",
    shortLabel: "Big Door",
    levelId: "level-1",
    // Low and looking east, straight out through the twelve-metre opening.
    focus: { at: { x: 46, z: 9.5 }, distance: 18, height: 3.0, rotation: 1.5 },
    description:
      "Twelve metres of hangar door, open onto the apron, with the bench inside it. The reason a company rents one of these rather than a floor of an office block.",
  },
  {
    id: "mezzanine",
    number: "04",
    label: "The Mezzanine",
    shortLabel: "Mezzanine",
    levelId: "level-mezz",
    // `height` is metres above *this* level's floor, so 3.0 here is standing on
    // the deck rather than 3 m off the concrete.
    focus: { at: { x: 46, z: 25 }, distance: 13, height: 3.0, rotation: 2.4 },
    description:
      "A deck four and a half metres up with another four and a half above it. Its own level, because a level is the only thing in this format that carries a floor height — and without one its chairs floated over bare concrete.",
  },
  {
    id: "galley",
    number: "05",
    label: "The Galley",
    shortLabel: "Galley",
    levelId: "level-1",
    focus: { at: { x: 9.5, z: 26 }, distance: 12, height: 3.2, rotation: 3.4 },
    description:
      "The lagoon side, and the only glazing you can see out of standing up. The whole social end of the building is arranged around one row of windows.",
  },
];

// ---- The pack -------------------------------------------------------------

// ---- The mezzanine, as its own level --------------------------------------
//
// Authored in its own floor's frame, with the deck at zero. `Plan` adds
// `MEZZ_HEIGHT` to every coordinate here exactly once.

const MEZZ_ROOMS: Room[] = [
  {
    id: "mezzanine",
    name: "The Mezzanine",
    outline: rect(MEZZ_W, MEZZ_N, WIDTH - 0.4, DEPTH - 0.4),
    floor: WOOD,
    ceiling: null,
  },
];

/**
 * The balustrade, and — as in the reference pack's gallery — a **wall** and not
 * a prop, because `Plan` derives the walk collider from the wall list and the
 * drop is 4.4 m onto polished concrete. No openings: that is what a balustrade
 * is.
 */
const MEZZ_WALLS: Wall[] = [
  {
    id: "mezz-west",
    from: { x: MEZZ_W, z: MEZZ_N },
    to: { x: MEZZ_W, z: DEPTH - 0.4 },
    height: 1.1,
    surface: GLASS,
  },
  {
    id: "mezz-north",
    from: { x: MEZZ_W, z: MEZZ_N },
    to: { x: WIDTH - 0.4, z: MEZZ_N },
    height: 1.1,
    surface: GLASS,
  },
];

const MEZZ_SEATS: Seat[] = [
  { id: "mezz-01", position: { x: 44.0, z: 23.0 }, facing: NORTH, pose: "sit" },
  { id: "mezz-02", position: { x: 46.4, z: 23.0 }, facing: NORTH, pose: "sit" },
  { id: "mezz-03", position: { x: 48.8, z: 23.0 }, facing: NORTH, pose: "sit" },
];

const MEZZ_PROPS: Prop[] = [
  { id: "mezz-table", kind: MEETING_TABLE, position: { x: 46.4, z: 24.2 }, rotation: NORTH },
  ...scatter("mezz-chair", TASK_CHAIR, [
    { x: 44.0, z: 23.0 },
    { x: 46.4, z: 23.0 },
    { x: 48.8, z: 23.0 },
  ]),
  ...scatter("mezz-lounge", LOUNGE_CHAIR, [
    { x: 44.0, z: 27.4 },
    { x: 47.0, z: 27.4 },
  ], { rotation: SOUTH }),
  { id: "mezz-rug", kind: RUG, position: { x: 45.5, z: 27.4 }, rotation: NORTH, colorKey: "social" },
  // Half-depth plus a 25 mm reveal off the wall face, which is how the reference
  // pack stands the same asset against a wall — `EXT_FACE + 0.2` is the shelf's
  // *clearance* and leaves it floating 0.42 m out in the room.
  ...scatter("mezz-shelf", SHELF, grid(WIDTH - EXT_FACE - 0.2, 22.0, 1, 3, 0, 1.2), {
    rotation: EAST,
  }),
];

const MEZZ_ZONES: Zone[] = [
  { id: "zone-mezz", name: "Mezzanine", outline: rect(MEZZ_W, MEZZ_N, WIDTH - 0.4, DEPTH - 0.4), colorKey: "social" },
];

const LEVEL_MEZZ: Level = {
  id: "level-mezz",
  name: "The Mezzanine",
  elevation: MEZZ_HEIGHT,
  // What is above the deck is the same roof, so its storey height is whatever is
  // left of the shed.
  wallHeight: RIDGE - MEZZ_HEIGHT,
  wallThickness: INT_THICKNESS,
  wallSurface: PAINT,
  floorplan: {
    rooms: MEZZ_ROOMS,
    walls: MEZZ_WALLS,
    props: MEZZ_PROPS,
    seats: MEZZ_SEATS,
    zones: MEZZ_ZONES,
  },
};

const LEVEL_1: Level = {
  id: "level-1",
  name: "The Slab",
  elevation: 0,
  wallHeight: RIDGE,
  wallThickness: INT_THICKNESS,
  wallSurface: PAINT,
  floorplan: {
    rooms: ROOMS,
    walls: WALLS,
    props: PROPS,
    deskBanks: DESK_BANKS,
    seats: SEATS,
    zones: ZONES,
  },
};

export const FRONTIER_VALLEY: Office = {
  id: "frontier-valley",
  name: "Frontier Valley",
  levels: [LEVEL_1, LEVEL_MEZZ],
  viewpoints: VIEWPOINTS,
  /**
   * Alameda Point, on the estuary side of Alameda Island.
   *
   * Typed by hand from the street grid of the former Naval Air Station, not
   * geocoded — CONTRACT.md §8. Four metres of elevation because this is
   * reclaimed flat ground and the slab is barely above it, which is the exact
   * opposite of `lumbridge-hq`'s 188 m and is the whole point of having both.
   *
   * `heading: 0` is a real claim rather than the reference pack's convenience:
   * the hangars here are laid out square to the old runways, which run close
   * enough to north–south that calling the clerestory wall "north" is true.
   * So the high glazing really does take north light and the lagoon really is
   * to the south.
   */
  site: FRONTIER_VALLEY_SITE,
  meta: {
    description:
      "A startup in a hangar at Alameda Point: one room, fifty-four by thirty, nine metres to the trusses. The second pack, and the one that shows the format describes a shed as well as it describes a corridor.",
    author: "Lumbridge",
    license: "CC0-1.0",
    version: "1.0.0",
    updated: "2026-08-07",
  },
};

export default FRONTIER_VALLEY;
