{"id":193545,"date":"2026-06-22T12:32:07","date_gmt":"2026-06-22T16:32:07","guid":{"rendered":"https:\/\/ccstudiosmiami.com\/video-studio-rental-miami\/"},"modified":"2026-10-07T20:57:56","modified_gmt":"2026-10-08T00:57:56","slug":"renta-de-estudio-de-video-miami","status":"publish","type":"page","link":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/","title":{"rendered":"Renta de Estudio de Video en Miami"},"content":{"rendered":"<div class=\"et_pb_section_0 et_pb_section et_section_regular et_block_section hm-herosec\" id=\"hero\"><div class=\"et_pb_row_0 et_pb_row et_block_row\"><div class=\"et_pb_column_0 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_0 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><link rel=\"preload\" as=\"font\" type=\"font\/ttf\" href=\"https:\/\/fonts.gstatic.com\/s\/bodonimoda\/v28\/aFT67PxzY382XsXX63LUYL6GYFcan6NJrKp-VPjfJMShrpsGFUt8oZDdwIA.ttf\" crossorigin><style>:root {\n  --accent: #000000;\n  --ash: #000000;\n  --bg: var(--ivory);\n  --bg-alt: var(--warm-white);\n  --black: #0B0A09;\n  --btn-radius: 0px;\n  --fg: var(--ink);\n  --fg-alt: var(--ink);\n  --font-body: 'Montserrat', -apple-system, sans-serif;\n  --font-display: 'Bodoni Moda', Georgia, serif;\n  --graphite: #3a352f;\n  --ink: #141210;\n  --ivory: #F9F0E0;\n  --ivory-deep: #F1E6D2;\n  --line: rgba(20,18,16,0.14);\n  --warm-white: #FCF8F0;\n}\n\n\/* Exact font files used by the approved interactive library.\n   A unique family name prevents WordPress\/Divi from satisfying the request with\n   another Bodoni Moda file under the same family name. *\/\n@font-face {\n  font-family: 'CC Bodoni Moda';\n  font-style: normal;\n  font-weight: 500;\n  font-display: swap;\n  src: url('https:\/\/fonts.gstatic.com\/s\/bodonimoda\/v28\/aFT67PxzY382XsXX63LUYL6GYFcan6NJrKp-VPjfJMShrpsGFUt8oXzawIA.ttf') format('truetype');\n}\n:root {\n  --font-display: 'CC Bodoni Moda', 'Bodoni Moda', Georgia, serif;\n}\n@font-face {\n  font-family: 'CC Bodoni Moda';\n  font-style: normal;\n  font-weight: 600;\n  font-display: swap;\n  src: url('https:\/\/fonts.gstatic.com\/s\/bodonimoda\/v28\/aFT67PxzY382XsXX63LUYL6GYFcan6NJrKp-VPjfJMShrpsGFUt8oZDdwIA.ttf') format('truetype');\n}\n\n\/* scale.css \u2014 reusable type, spacing and motion roles.\n   Loaded after tokens.css and before base.css. HOME's token values remain\n   mirrored in tokens.css; this file supplies additional component roles.\n\n   Owner correction 2026-09-16: preserve HOME's normal section-heading scale\n   (Bodoni Moda, clamp(28px, 6vw, 46px), weight 600) and its component-specific\n   spacing. The display\/H2 variables below do not replace base.css's .bk-h2.\n   Existing roles are retained for their consumers, not applied as a mandatory\n   heading ladder. Component optical exceptions remain documented in shared source.\n   The 4px-based spacing roles support reuse without flattening HOME's composition. *\/\n\n:root {\n  --t-hero-size: clamp(34px, 4.5vw, 60px);\n  --t-hero-lh: 1.08;\n  --t-hero-ls: -0.015em;\n  \/* ---- reusable type roles ---------------------------------------------- *\/\n  \/* Optional display role. Normal HOME headings use their component\/base rules. *\/\n  --t-display-size: clamp(38px, 5.6vw, 58px);\n  --t-display-lh: 1.02;\n  --t-display-ls: -0.02em;\n\n  --t-h2-size: clamp(29px, 3.4vw, 42px);\n  --t-h2-lh: 1.08;\n  --t-h2-ls: -0.015em;\n  \/* The same title role inside a single column no wider than 480px (the standalone \/links\/ page, 2026-10-01).\n     --t-h2 scales with the VIEWPORT, the column does not: at 1440 the role's 42px drew \"Content Studio in Miami\"\n     467px wide in a 456px column, and at 320 its 29px floor drew it 322px in 296px -- a third title line either\n     way. The cap is the column (minus its two --s-3 gutters) over that line's measured advance in the system face,\n     11.1em, plus 4%. Every width from 360 to 414 keeps the plain role (29px). *\/\n  --t-column-title-size: min(var(--t-h2-size), calc((min(100vw, 480px) - 2 * var(--s-3)) \/ 11.6));\n\n  --t-h3-size: clamp(20px, 1.9vw, 25px);\n  --t-h3-lh: 1.18;\n  --t-h3-ls: -0.01em;\n\n  \/* Numerals are their own role: they need tabular figures so a price column\n     aligns, and they should never inherit a heading's optical letter-spacing. *\/\n  --t-numeral-size: clamp(28px, 2.6vw, 36px);\n  --t-numeral-lh: 1;\n  --t-numeral-ls: -0.015em;\n\n  --t-lead-size: 17px;\n  --t-lead-lh: 1.55;\n\n  --t-body-size: 16px;\n  --t-body-lh: 1.70;\n\n  --t-meta-size: 13px;      \/* replaces 12.5 \/ 13 \/ 13.5, which were one job *\/\n  --t-meta-lh: 1.45;\n  \/* The meta role for a line that must stay ONE line on the narrowest phones (owner 2026-10-02, \/links\/ route cards:\n     \"make all sub text in the button fit on one line no matter the break point\"). 13px from 375px up; below that it\n     steps down with the screen (12.3px at 360, 11.5px at 344, 10.2px at 320), sized so the longest \/links\/ route line\n     (245px at 13px) fits its card. tests\/test_links_page.py measures every line at 320-1440. *\/\n  --t-meta-fit-size: min(var(--t-meta-size), calc(5.2vw - 6.4px));\n\n  --t-ui-size: 12px;        \/* buttons and controls *\/\n  --t-ui-lh: 1;\n  --t-ui-ls: 0.16em;\n\n  --t-micro-size: 11px;     \/* replaces three different 10.5px treatments *\/\n  --t-micro-lh: 1.25;\n  --t-micro-ls: 0.10em;\n\n  \/* ---- spacing: 4px base ------------------------------------------------- *\/\n  --s-1: 4px;\n  --s-2: 8px;\n  --s-3: 12px;\n  --s-4: 16px;\n  --s-5: 24px;    \/* shared spacing role; component gaps retain their documented values *\/\n  --s-6: 32px;\n  --s-7: 48px;\n  --s-8: 64px;\n  --s-9: 96px;\n  --s-10: 128px;\n\n  \/* ---- section rhythm ---------------------------------------------------- *\/\n  \/* Available section roles. Base .bk-section and component-specific rules\n     determine actual padding; these variables are not assigned automatically. *\/\n  --sec-lg: var(--s-10);\n  --sec: var(--s-9);\n  --sec-sm: var(--s-8);\n\n  \/* ---- motion ------------------------------------------------------------ *\/\n  \/* Shared transition durations. Preserve each component's documented timing\n     and reduced-motion behavior when it consumes or extends these roles. *\/\n  --motion-fast: 120ms;\n  --motion-base: 250ms;\n  --motion-slow: 400ms;\n  --motion-ease: cubic-bezier(0.2, 0.7, 0.3, 1);\n}\n\n@media (max-width: 600px) {\n  :root {\n    --sec-lg: 72px;\n    --sec: 56px;\n    --sec-sm: 40px;\n  }\n}\n\n\/* base.css \u2014 layout primitives lifted verbatim from HOME's live CSS\n   (reference\/home.css). Every selector is scoped to .et-l--post per\n   the project's CSS-specificity rule (winning specificity is\n   body[class] .et-l--post <sel>). Do not hand-invent a rule here \u2014\n   re-run refresh_reference.py and re-extract if HOME changes.\n\n   Where HOME shipped two conflicting declarations for the same selector\n   (a base rule plus a later, higher-cascade-order override), the rule\n   that actually wins on the live page is the one transcribed below. *\/\n\n\/* box-sizing, and why it is here rather than assumed.\n   Measured 2026-09-14: `grep box-sizing` across the whole system returned ZERO hits.\n   .btn--block is width:100% with 38px horizontal padding and a 1px border, so inside\n   the 1180px container it computed 1258px and overflowed by 78px -- visible as the\n   ivory ADD EDITING button hanging past the price card above it. A 78px overshoot\n   reads worse than an obvious break, because it looks like a decision. *\/\n.et-l--post,\n.et-l--post *,\n.et-l--post *::before,\n.et-l--post *::after {\n  box-sizing: border-box;\n}\n\n\/* .bk-section \u2014 section wrapper padding *\/\n.et-l--post .bk-section {\n  padding: clamp(48px, 8vw, 96px) 0;\n}\n@media (max-width: 760px) {\n  .et-l--post .bk-section {\n    padding-top: 32px !important;\n    padding-bottom: 32px !important;\n  }\n}\n\n\/* SECTION SPACING CONDITIONS -- owner 2026-09-24: \"We should have spacing conditions\n   in place. I didn't ask for no space I asked for standard normal looking.\"\n   tools\/cc_system\/spacing.py derives every boundary from each component's `spacing`\n   role in components.json; build.py emits the result as bk-gap-* classes on the Divi\n   section; these rules are the ONLY place a system section's vertical padding is set.\n   Component stylesheets never pad their own section root (tests\/test_spacing_conditions\n   enforces it), and spacing.py check measures the rendered gaps against the conditions.\n     std    ordinary boundary                     --sec-y each side\n     rel    inside the reviews\/press\/feed group   --sec-y-rel each side\n     none   embed bottom; media meeting media or closing the page\n     embed  after an embed: tops its own blank inset up to the standard gap *\/\n.et-l--post {\n  --sec-y: clamp(32px, 4vw, 48px);\n  --sec-y-rel: clamp(24px, 2.25vw, 32px);\n}\n.et-l--post .et_pb_section.bk-gap-t--std [data-screen-label].bk-section { padding-top: var(--sec-y) !important; }\n.et-l--post .et_pb_section.bk-gap-b--std [data-screen-label].bk-section { padding-bottom: var(--sec-y) !important; }\n.et-l--post .et_pb_section.bk-gap-t--rel [data-screen-label].bk-section { padding-top: var(--sec-y-rel) !important; }\n.et-l--post .et_pb_section.bk-gap-b--rel [data-screen-label].bk-section { padding-bottom: var(--sec-y-rel) !important; }\n.et-l--post .et_pb_section.bk-gap-t--none [data-screen-label].bk-section { padding-top: 0 !important; }\n.et-l--post .et_pb_section.bk-gap-b--none [data-screen-label].bk-section { padding-bottom: 0 !important; }\n.et-l--post .et_pb_section.bk-gap-t--embed [data-screen-label].bk-section {\n  padding-top: max(0px, calc(2 * var(--sec-y) - var(--embed-inset-bottom, 0px))) !important;\n}\n\n\/* Owner 2026-09-24, same seam as HOME's map band (map.css): the footer's own\n   `border-top: 1px solid var(--line)` plus the 1px sticky anchor read as a grey line\n   under the closing media. The footer CSS is inline in the Divi Theme Builder and not\n   REST-writable, so this is the page-payload exception to `.et-l--post` scoping.\n   spacing.py adds the class to a page's last section when it is edge-to-edge media. *\/\nbody:has(.et-l--post .bk-section--flush-footer) .bk-footer {\n  border-top: 0;\n  margin-top: -1px;\n}\n\n\/* .bk-section--tight \u2014 the standard system section (every `content`, `proof`,\n   `media` and `embed` component). Its value is the spacing token; the derived\n   bk-gap-* classes above decide each edge on a built page. *\/\n.et-l--post .bk-section--tight {\n  padding: var(--sec-y) 0;\n}\n\n\/* .container-bk \u2014 section content width *\/\n.et-l--post .container-bk {\n  width: min(1180px, 92vw);\n  margin: 0 auto;\n}\n\n\/* .bk-h2 \u2014 section heading. HOME's base rule sets font-weight: 500, but\n   a later compound rule (.bk-h2, .hm-hero__title, ... { font-weight:\n   600 !important; }) wins the cascade regardless of source order. Only\n   the .bk-h2-relevant weight is transcribed here; the compound\n   selector's other classes belong to components not yet in this\n   system. *\/\n.et-l--post .bk-h2 {\n  font-family: var(--font-display);\n  font-weight: 600 !important;\n  font-size: clamp(28px, 6vw, 46px);\n  line-height: 1.04;\n  letter-spacing: -0.01em !important;\n  color: var(--ink) !important;\n  margin: 0;\n  padding: 0 0 10px;\n  text-wrap: balance;\n}\n\n\/* The theme forces h2 to 18px on very narrow phones. Keep normal section\n   headings on HOME's scale; explicit quiet\/loud variants retain their own roles. *\/\n.et-l--post .bk-section:not(.bk-section--quiet):not(.bk-section--loud) .bk-h2 {\n  font-size: clamp(28px, 6vw, 46px) !important;\n}\n\n\/* .bk-lead \u2014 section lead paragraph *\/\n.et-l--post .bk-lead {\n  font-size: var(--t-body-size);\n  text-wrap: balance;\n  font-weight: 500;\n  color: var(--graphite);\n  line-height: 1.6;\n  max-width: 56ch;\n  margin: 12px 0 0;\n}\n\n\/* .reveal \u2014 scroll-in animation primitive. The \"revealed\" state and the\n   .reveal-armed unrevealed state are one mechanism; both are transcribed\n   so the primitive actually animates. Values are HOME's winning\n   (higher cascade order) declaration: .8s \/ translateY(24px). *\/\n.et-l--post .reveal {\n  opacity: 1;\n  transform: none;\n  transition: opacity .8s cubic-bezier(.2,.7,.3,1), transform .8s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .reveal-armed .reveal:not(.in) {\n  opacity: 0;\n  transform: translateY(24px);\n}\n\n\/* FIX 4: .reveal runs a fade\/translate on every section (via .reveal-armed\n   above) and had no prefers-reduced-motion counterpart at all \u2014 the only\n   reduced-motion query in the whole system gated the press marquee\n   (press.css's .ccp-track), leaving this, the mechanism that actually fires\n   on every section, ungated. Removing just the transition is not enough:\n   a page whose JS arms .reveal-armed before the intersection observer adds\n   .in would leave the untransitioned element stuck at opacity:0 forever \u2014\n   worse than the motion it replaces. Both declarations are neutralised\n   together so content is always visible under reduced motion, regardless\n   of .reveal-armed\/.in state. *\/\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .reveal {\n    transition: none;\n  }\n  .et-l--post .reveal-armed .reveal:not(.in) {\n    opacity: 1;\n    transform: none;\n  }\n}\n\n\/* Base section ground \u2014 the other half of the tone system.\n\n   HOME paints EVERY section ivory and lets .hm-tone-d opt out. Only the opt-out\n   below was transcribed, so every section that is not .hm-tone-d fell through to\n   Divi's own dynamic rule (.et_pb_section{background-color:rgb(255,255,255)},\n   specificity 0,1,0, no !important) and rendered WHITE. That is the mechanism\n   behind the \/podcast-studio-miami\/ 4\/10 build: measured live 2026-09-13, all 15\n   sections computed rgb(255,255,255) while HOME alternates #F9F0E0 \/ #F1E6D2.\n\n   Verified live on the broken page: this rule at (0,2,0) + !important beats\n   Divi's (0,1,0), turning 15 white sections ivory; .hm-tone-d below is (0,3,0)\n   and still wins, so the opt-out is unaffected.\n\n   Transcribed byte-for-byte from reference\/home.css. The descendant combinator\n   is load-bearing: `.et-l--post.et_pb_section` (no space) matches no element on\n   any page. tests\/test_cc_system_divi_nesting.py guards the difference. *\/\n.et-l--post .et_pb_section {\n  background-color: var(--ivory) !important;\n}\n\n\/* .hm-tone-d \u2014 deeper-ivory section tone *\/\n.et-l--post .et_pb_section.hm-tone-d {\n  background-color: var(--ivory-deep) !important;\n}\n\n\/* a \u2014 bare inline links in body copy (FIX 2). HOME's own scoped rule for\n   this exact selector (reference\/home.css: `.et-l--post a`, declaring\n   colour:inherit and text-decoration:none) was never transcribed into this\n   system at all, so any bare <a> sitting in ordinary body copy fell through\n   to the true browser default instead \u2014 blue, underlined \u2014 a foreign\n   colour on a palette of ivory + black, taupe on hover\/active only.\n   Confirmed live on the mock at both breakpoints: \"Just need the room?\",\n   \"3D studio tour\", \"video studio rental\".\n\n   Deliberate divergence from HOME's own value here (second one in this\n   system; see the .hm-scrim\/F4 note further down for the first, and the\n   same reasoning applies): HOME's colour:inherit \/ text-decoration:none is\n   not a visible link style, it is a blank slate \u2014 every link surface HOME\n   actually ships (.foot-areas a, .bk-trust__item, .rate-tile,\n   .hm-close__contact a, ...) layers its own explicit, visible treatment on\n   top of it. A bare link in plain body copy that never got one of those\n   layered treatments would render on HOME exactly as it did here:\n   indistinguishable from the surrounding text, no colour or shape cue that\n   it's interactive at all \u2014 its own accessibility gap (WCAG 1.4.1, use of\n   colour\/shape alone), not a stylistic choice worth reproducing. Given a\n   choice between transcribing an invisible link and shipping a visible\n   one, this system ships the visible one. Matches this system's own\n   .hm-hero__alt treatment (explicit colour + underline + underline-offset),\n   recoloured for ivory body copy \u2014 ink instead of ivory \u2014 with taupe on\n   hover only, per the palette rule. More specific rules already in this\n   system win the cascade over this unchanged: .btn, .hm-hero__alt,\n   .bk-trust__item, .pk-note a, .ccp-logo, and sticky.css's own unscoped\n   .stickybar .btn--bar. *\/\n.et-l--post a {\n  color: var(--ink);\n  text-decoration: underline;\n  text-decoration-color: var(--btn-ghost-line);\n  text-underline-offset: 3px;\n}\n.et-l--post a:hover {\n  color: #8D8175;\n  text-decoration-color: currentColor;\n}\n\n\/* .btn \u2014 base button.\n\n   Fix round 3, FIX 2: HOME's live page has no global `a{text-decoration:none}`\n   of its own \u2014 it inherits one from Divi's external theme stylesheet, which\n   this system never loads (and the local mock, correctly, does not fake).\n   Without it `.btn`'s label rendered underlined, since `.btn` is an `<a>` and\n   nothing here ever cleared the UA-default anchor underline. Declared\n   directly so the button is self-sufficient and does not depend on a theme\n   reset it does not ship. *\/\n.et-l--post .btn {\n  font-family: var(--font-body);\n  font-weight: 600;\n  font-size: var(--t-ui-size);\n  letter-spacing: 0.22em;\n  text-transform: uppercase;\n  text-decoration: none;\n  display: inline-flex;\n  align-items: center;\n  gap: 0.7em;\n  padding: 18px 38px;\n  line-height: 1.35;  \/* set here, not inherited: one 58px button in every section (owner 2026-09-30) *\/\n  \/* 2026-10-01: 58px came only from the 15px .arrow's line box (20.25px). A label without the arrow\n     span (\"Book Now\", \"Start My Membership \u2192\" with a text arrow) measured 54px. The floor makes the\n     height independent of the label. Border-box (top of this file), so it includes padding. *\/\n  min-height: 58px;\n  border-radius: var(--btn-radius);\n  cursor: pointer;\n  border: 1px solid transparent;\n  transition: transform .35s cubic-bezier(.2,.7,.3,1), background .35s ease, color .35s ease, opacity .3s;\n  white-space: nowrap;\n}\n.et-l--post .btn:hover {\n  transform: translateY(-2px);\n}\n.et-l--post .btn .arrow {\n  font-size: 15px;\n  transition: transform .35s;\n}\n.et-l--post .btn:hover .arrow {\n  transform: translateX(4px);\n}\n\n\/* .btn--solid \u2014 DESIGN.md primary: true-black fill and ivory label. *\/\n.et-l--post .btn--solid {\n  background: var(--accent) !important;\n  color: var(--ivory) !important;\n}\n.et-l--post .btn--solid:hover {\n  opacity: 0.88;\n}\n\n\/* Ivory tone variables \u2014 fix round 1 (task-4b-report.md), ruling on\n   FIX 3. HOME defines --page-bg, --tone-a-\u2026, --tone-b-\u2026, --nav-\u2026, --btn-bg,\n   --btn-fg\/--btn-ghost-fg\/--btn-ghost-line\/--hero-fg inside\n   [data-dir=\"ivory\"] and [data-dir=\"noir\"] tone wrappers (reference\/\n   home.css, offset ~62103), so .btn--ghost below never had anything to\n   resolve: this system emits no [data-dir] wrapper anywhere. Ruling:\n   this site is ivory-grounded, so only the ivory set is applied here,\n   at the system root, rather than requiring every component to emit a\n   [data-dir=\"ivory\"] wrapper of its own. The noir set is NOT added \u2014\n   nothing in this system needs it, and unused configurability is not\n   wanted. These are not part of Task 1's 16-token tokens.css (and must\n   not be \u2014 a test asserts tokens.css matches reference\/home-tokens.json\n   exactly), so they live here instead. *\/\n.et-l--post {\n  \/* Page-container ground, transcribed from reference\/home.css:\n     `.et-l--post{background:var(--ivory);font-weight:500;color:var(--ink);}`.\n     Until now this block declared --page-bg\/--tone-a-bg and never painted them,\n     so .et-l--post computed rgba(0,0,0,0) over a white body: the tokens existed\n     and nothing consumed them. Both this and the .et_pb_section rule above are\n     load-bearing \u2014 fixing either alone still leaves the page wrong. *\/\n  background: var(--ivory);\n  font-weight: 500;\n  color: var(--ink);\n  --page-bg: var(--ivory);\n  --tone-a-bg: var(--ivory);\n  --tone-a-fg: var(--ink);\n  --tone-b-bg: var(--warm-white);\n  --tone-b-fg: var(--ink);\n  --nav-bg: rgba(249,240,224,0.86);\n  --nav-fg: var(--ink);\n  --btn-bg: var(--accent);\n  --btn-fg: var(--ivory);\n  --btn-ghost-fg: var(--ink);\n  --btn-ghost-line: rgba(20,18,16,0.45);\n  --hero-fg: var(--ink);\n}\n\n\/* .btn--ghost \u2014 outline button. HOME defines this using tone-scoped\n   custom properties (--btn-ghost-fg, --btn-ghost-line, --page-bg) set on\n   [data-dir=\"ivory\"] \/ [data-dir=\"noir\"] wrappers, which are not part of\n   Task 1's 16-token tokens.css. Transcribed verbatim; the ivory tone\n   block above (fix round 1) now supplies --btn-ghost-fg\/--btn-ghost-line\n   at the system root, so .btn--ghost resolves without a component\n   needing to emit its own data-dir wrapper. See task-2-report.md and\n   task-4b-report.md's fix round 1. *\/\n.et-l--post .btn--ghost {\n  background: transparent;\n  color: var(--btn-ghost-fg);\n  border-color: var(--btn-ghost-line);\n}\n.et-l--post .btn--ghost:hover {\n  background: var(--btn-ghost-fg);\n  color: var(--page-bg);\n}\n\n\/* .btn--bar \u2014 REMOVED from base.css, 2026-09-14. This rule and its :hover carried the\n   `.et-l--post` prefix \"per the scoping rule\", and MEASURED, the sticky bar is a direct\n   child of <body> on a built page and in the styleguide alike: it is never inside\n   `.et-l--post`, so neither rule could ever match. SYSTEM.md already records `sticky` as\n   the one deliberate divergence from the scoping rule; this was that divergence applied\n   to the stylesheet and then un-applied to the markup, and nothing noticed because a\n   selector that matches nothing costs nothing visible.\n\n   It was also STALE, which is what makes it worth removing rather than leaving: it kept\n   `padding: 13px 26px` from before the Task 10 tap-target fix, while the live rule in\n   sticky.css carries `15px 26px`. Had the scoping ever been \"corrected\" to make this\n   rule match, it would have won on specificity and silently regressed the sticky CTA\n   from 45px back to 41px -- under the 44px minimum, on the page's most-used control.\n\n   The live declarations are sticky.css's unscoped `.stickybar .btn--bar`, unchanged.\n   Found by tests\/test_scale_consumers_render.py. *\/\n\/* .btn--block \u2014 full-width variant for a lone CTA that follows a full-width\n   text or price block (FIX 1). `.btn` sizes to its label, never its\n   container, so a single button left after a wide block (a price table in\n   #editing, the whole hero content column, the offer card's feature grid)\n   strands far short of that block's own right edge \u2014 worst case, #editing's\n   \"EMAIL ABOUT EDITING\" (272px) under price rows spanning 1180px at 1440px,\n   a ~900px gap. Close is unaffected: two buttons in .stack-cta already read\n   as a row and need no change.\n\n   Chosen fix (of the two options in the brief): an explicit stretch variant,\n   not a shared max-width constraining the wide block down to button size \u2014\n   the price rows (.shoot-row) and the feature grid (.incl-cards) are\n   supposed to run the block's full width, so shrinking THEM to match the\n   button would fight their own layout intent. Stretching the lone button\n   to its own container's width instead resolves the right edge without\n   touching either of those. `display:flex` alone already makes the box\n   block-level (it fills the containing block's width like a div would);\n   `width:100%` is kept for clarity, and `justify-content:center` re-centres\n   the label since the button no longer shrink-wraps it. Applied to hero's\n   primary CTA, #editing's CTA and the offer card's CTA \u2014 see SYSTEM.md for\n   the ruling recording `btn--block` as a class HOME does not ship. *\/\n.et-l--post .btn--block {\n  display: flex;\n  width: 100%;\n  justify-content: center;\n}\n\n\/* Focus-visible ring \u2014 FIX 8. Before this, only .ccp-logo (press.css) and\n   the tour-video facade (.cc-yt-facade, room.css) carried the branded taupe\n   ring; every other link and button fell back to the browser default\n   outline \u2014 inconsistent, not absent, but inconsistent enough that three\n   reviewers each flagged it. Extended here so the same ring applies to\n   every link and button system-wide. More specific component rules\n   (.ccp-logo, .cc-yt-facade) already declare their own outline-offset for\n   their own context and are unaffected \u2014 this only fills the gap\n   everywhere else. Never removes an indicator, only re-colours it. *\/\n.et-l--post a:focus-visible,\n.et-l--post button:focus-visible {\n  outline: 2px solid #8D8175;\n  outline-offset: 3px;\n}\n\n\/* @keyframes hmmarquee \u2014 HOME's marquee scroll animation (verbatim from\n   reference\/home.css), added by Task 3 for components\/marquee.css's\n   `animation: hmmarquee 32s linear infinite;`. It lives here rather than in\n   marquee.css because CSS keyframe selectors (from\/to\/%) cannot be prefixed\n   with .et-l--post, and this file \u2014 unlike components\/*.css \u2014 is not\n   covered by the per-component scoping test. *\/\n@keyframes hmmarquee {\n  to {\n    transform: translateX(-50%);\n  }\n}\n\n\/* @keyframes ccp-scroll \u2014 HOME's press-logo marquee scroll animation\n   (verbatim from reference\/home.css, offset ~57606), added by Task 4b for\n   components\/press.css's `animation: ccp-scroll 50s linear infinite;`. Same\n   reason as @keyframes hmmarquee above: from\/to selectors cannot be\n   prefixed with .et-l--post, and components\/press.css IS covered by the\n   per-component scoping test. *\/\n@keyframes ccp-scroll {\n  from {\n    transform: translateX(0);\n  }\n  to {\n    transform: translateX(-50%);\n  }\n}\n\n\n\/* Divi's row geometry for these pages, carried in the page CSS (owner 2026-10-02: \"flickers\").\n   Not invented: these are the values Divi's own per-page module CSS gives every section, row and\n   code module of a system page (et-builder-module-design-*-cached-inline-styles, read on draft\n   195947). Divi prints that block after the hero whenever its et-cache file is missing -- on every\n   draft and on a live page after each content change -- so the page first painted with Divi's\n   default row (80% wide, padded) and snapped full width ~2 s later (filmed: film-after\/christmas).\n   This page CSS rides inline before the hero, so the first paint already has the final geometry.\n   Its own file, outside base.css, so the standalone \/links\/ page (its own Divi rows, measured byte\n   budget) is unchanged; registry.system_css() places it right after base.css. *\/\n.et-l--post .et_pb_section {\n  padding: 0;\n}\n.et-l--post .et_pb_row {\n  width: 100% !important;\n  max-width: 100% !important;\n  padding: 0 !important;\n}\n.et-l--post .et_pb_code {\n  margin-bottom: 0 !important;\n}\n\n\/* Phase 2 booking embed. Acuity owns its service choices and prices. The shared\n   CC heading sits inside the scheduler shell so the page does not repeat those\n   choices in a second interface immediately above the live calendar. *\/\n.et-l--post .cc-booking > .container-bk {\n  scroll-margin-top:calc(var(--cc-header-height) + 16px);\n}\n\/* Owner 2026-09-24: the heading and scheduler sit on the section's own ivory, with no\n   card fill or outline, so the booking task reads as part of the page. The heading\n   keeps the section's single alignment axis; Acuity paints its own ivory.\n\n   Acuity paints blank space inside its own frame -- 37px above its first heading and\n   ~77px below \"Check Code Balance\" (footer 22 + wrapper 33 + a tracking-frame line),\n   none of it reachable with Acuity's supported selectors. That inset IS the spacing:\n   the lead sits directly on the frame, and the section after the embed only tops the\n   77px up to the standard boundary (base.css bk-gap-t--embed). spacing.py check\n   re-measures the inset inside the frame on every render. *\/\n.et-l--post {\n  --embed-inset-bottom: 77px;\n}\n.et-l--post .cc-booking__intro {\n  display:grid;\n  gap:16px;\n  padding:0;\n}\n.et-l--post .cc-booking__intro .bk-lead {\n  margin:0;\n  max-width:62ch;\n}\n.et-l--post .cc-booking__calendar {\n  position:relative;\n}\n.et-l--post .cc-booking__calendar iframe {\n  display:block;\n  width:100%;\n  min-height:1220px;\n  border:0;\n  background:transparent;\n}\n@media (min-width:760px) {\n  .et-l--post .cc-booking__intro {\n    grid-template-columns:minmax(0,1.1fr) minmax(280px,.9fr);\n    align-items:center;\n  }\n  \/* The reservation must stay BELOW the scheduler's content height: Acuity's embed\n     script only grows a frame to its content, so a taller reservation (1120 against\n     1109 of content, measured 2026-09-24) stays as blank space inside the frame. *\/\n  .et-l--post .cc-booking__calendar iframe { min-height:1000px; }\n}\n\n\/* Phase 2 (owner 2026-09-27): the scheduler over the page, on the choice the visitor tapped. *\/\n.et-l--post .cc-book-sheet { display: contents; }\n.et-l--post .cc-book-sheet__dialog { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: var(--ivory); color: var(--ink); }\n.et-l--post .cc-book-sheet__dialog[open] { display: flex; flex-direction: column; }\n.et-l--post .cc-book-sheet__dialog::backdrop { background: rgba(20, 18, 16, .5); }\n.et-l--post .cc-book-sheet__bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); min-height: 60px; padding: var(--s-2) var(--s-3) var(--s-2) var(--s-5); border-bottom: 1px solid var(--line); background: var(--ivory); }\n.et-l--post .cc-book-sheet__title { margin: 0; font: 600 20px\/1.2 var(--font-display); color: var(--ink); }\n.et-l--post .cc-book-sheet__close { flex: none; width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 0; background: var(--warm-white); color: var(--ink); font: 400 26px\/1 var(--font-body); cursor: pointer; }\n.et-l--post .cc-book-sheet__close:hover { background: #8D8175; color: var(--black); }\n.et-l--post .cc-book-sheet__frame { flex: 1 1 auto; width: 100%; min-height: 0; border: 0; background: var(--ivory); }\n@media (min-width: 900px) {\n  .et-l--post .cc-book-sheet__dialog { width: min(760px, 92vw); height: min(900px, 92dvh); margin: auto; border: 1px solid var(--line); }\n}\n\n\/* close.css \u2014 HOME's closing CTA band (.hm-close), extracted verbatim\n   from reference\/home.css (offset ~91544-92330, one contiguous block,\n   already .et-l--post-scoped in the source), with deliberate divergence\n   per F9\/F10.\n\n   F9: the source rule ships a centring text-align declaration on\n   .hm-close (value: center), and margin:14px auto 28px on .hm-close p\n   (the \"auto\" left\/right margin centres the 46ch-capped paragraph).\n   That pairing is the root of the defect this component exists to fix\n   on the page it replaces \u2014 a centred heading\/lead over a button row\n   that then overflows a 420-pixel-wide cap and shoves right (that\n   page's own CSS is not part of this system; see task-4-brief.md). Both\n   are dropped here so the band reads left-aligned top to bottom: the\n   centring declaration is removed from .hm-close, and .hm-close p's\n   margin is 14px 0 28px (no auto).\n\n   Fix round 1, FIX 1 (Critical): .hm-close h2's own local block shipped\n   font-weight: 500, but reference\/home.css also carries a second,\n   unconditional compound rule at offset ~108275 \u2014 a comma-separated\n   list of eleven selectors including .bk-h2 and .hm-close h2 \u2014 that\n   sets font-weight: 600 !important. !important wins regardless of\n   specificity or source order, so HOME's live .hm-close h2 renders at\n   600, not 500. base.css already documents this exact compound rule for\n   its sibling .bk-h2 (base.css:33-38); the same precedent applies here.\n   The winning value (600 !important) is transcribed below. No other\n   declaration in .hm-close \/ .hm-close h2 \/ .hm-close p is affected by\n   that compound rule \u2014 re-checked every selector this component and\n   the other five components in this task use against the full\n   comma-list; the compound rule only touches .hm-close h2.\n\n   F10: .hm-close__contact \u2014 HOME's own place for a plain grey contact\n   line, and exactly the \"bare grey address\" named in the defect \u2014 is\n   deliberately NOT extracted. This component never carries an address;\n   that belongs to the location component only.\n\n   Buttons: fix round 1, FIX 2 \u2014 .stack-cta is extracted below (offset\n   ~78667 in reference\/home.css: display:flex; gap:16px; flex-wrap:wrap;\n   no cascade conflict, single declaration). It was previously described\n   in this comment as a base.css primitive; it never shipped anywhere in\n   the system, so the two CTA buttons had no flex\/gap and fell back to\n   block layout. .stack-cta--center (the same offset, justify-content:\n   center) is NOT extracted \u2014 this component never uses that modifier,\n   and adding it would be unused configurability.\n\n   Fix round 1, FIX 3 \u2014 the secondary action now uses .btn--ghost, not a\n   bare .btn. .btn--ghost's --btn-ghost-fg\/--btn-ghost-line previously\n   had nowhere to resolve, because HOME scopes them to a [data-dir]\n   wrapper this system never emitted; base.css now applies the ivory set\n   of those tone variables at the system root (see base.css's own note),\n   so .btn--ghost renders correctly here without this component needing\n   to emit a [data-dir] wrapper itself. *\/\n\/* GROUND REMOVED 2026-09-14. This rule painted `var(--ivory-deep)` on the closing band\n   itself, making `close` the one component that authored its own ground -- against\n   MASTER.md rule 4 (\"Grounds are derived, never authored\") and against the tone law's\n   own guarantee that a page closes on base. `components.json` declares this component\n   `ground: \"base\"`, and `build.ground_tones()` now derives grounds from that field, so\n   this line was a second authority quietly overruling the first on every page.\n\n   Found by the senior-UI seat measuring the last section of a built page and getting\n   rgb(241,230,210) where the derivation said base. The band keeps its hairline top\n   rule, which is what actually separates it from the section above. *\/\n.et-l--post .hm-close {\n  color: var(--ink);\n  padding: clamp(48px, 9vw, 90px) 0;\n  border-top: 1px solid var(--line);\n}\n.et-l--post .hm-close h2 {\n  font-family: var(--font-display);\n  font-weight: 600 !important;\n  font-size: clamp(30px, 7vw, 56px);\n  line-height: 1.02;\n  color: var(--ink);\n}\n.et-l--post .hm-close p {\n  font-family: var(--font-body);\n  font-size: var(--t-lead-size);\n  line-height: var(--t-lead-lh);\n  font-weight: 500;\n  color: var(--graphite);\n  margin: 14px 0 28px;\n  max-width: 46ch;\n}\n.et-l--post .stack-cta {\n  display: flex;\n  gap: 16px;\n  flex-wrap: wrap;\n}\n\n\/* Owner change requests 2026-09-26 (rates rebuild): \"I need a better table design especially for\n   mobile and it also does not line up with the left and right padding of the other sections\",\n   then \"still not design good enough or easy to understand. It is also very long on mobile.\"\n   Supersedes the 2026-09-17 compact phone layout and the two stacked phone layouts of Sept 26.\n\n   One comparison matrix at every width, in the language of HOME's rate ledger directly above it\n   (.cc-rates): micro column heads over an ink rule, hairline rows, left-aligned row labels. The\n   CC Studios column carries the ivory-deep tone as one continuous band, so the answer to \"what do\n   I get here\" is a single column of check marks read top to bottom. Answers are one word; a\n   stacked phone layout is what made the section long, so the three columns never stack. The\n   section shares HOME's container edges (no narrower cap). *\/\n.et-l--post .cc-comparison__intro { margin: 0 0 var(--s-6); }\n.et-l--post .cc-comparison__label { font: 500 12px\/1.5 var(--font-body); letter-spacing: .34em; text-transform: uppercase; margin: 0 0 18px; }\n.et-l--post .cc-comparison__label:empty { display: none; }\n.et-l--post .cc-comparison .bk-h2 { text-align: left; }\n.et-l--post .cc-comparison .bk-lead { max-width: 60ch; text-align: left; }\n\/* The theme's `.entry-content table:not(.variations)` draws a 1px #eee box and\n   `.entry-content tr th` turns every th #555 at 700; both are set explicitly here. *\/\n.et-l--post .cc-comparison table[role=\"table\"] { width: 100%; border: 0; border-collapse: collapse; table-layout: fixed; background: transparent; color: var(--ink); font-family: var(--font-body); }\n.et-l--post .cc-comparison th, .et-l--post .cc-comparison td { padding: 13px 12px; border: 0; border-bottom: 1px solid var(--line); text-align: center; vertical-align: middle; color: var(--ink); font-size: 15px; font-weight: 500; line-height: 1.3; overflow-wrap: normal; hyphens: manual; }\n.et-l--post .cc-comparison th:first-child { padding-left: 0; text-align: left; }\n.et-l--post .cc-comparison th:last-child, .et-l--post .cc-comparison td:last-child { padding-right: 0; }\n.et-l--post .cc-comparison thead th { padding-top: 0; padding-bottom: 10px; border-bottom-color: var(--ink); font-size: var(--t-micro-size); font-weight: 600; letter-spacing: var(--t-micro-ls); line-height: var(--t-micro-lh); text-transform: uppercase; color: var(--graphite); vertical-align: bottom; }\n.et-l--post .cc-comparison thead th:nth-child(2) { width: 24%; color: var(--ink); }\n.et-l--post .cc-comparison thead th:nth-child(3) { width: 28%; }\n\/* The answer column gives back 4px of its left padding so the longest answer, \"No siempre\",\n   stays on one line from 361px up; the row label wraps before an answer does. *\/\n.et-l--post .cc-comparison th:last-child, .et-l--post .cc-comparison td:last-child { padding-left: 8px; }\n\/* 2026-10-01 (A22): the CC Studios column no longer carries an ivory-deep band. On a phone it painted\n   13% of the ivory section as a tinted box. The column still reads first: ink header, 600 answers,\n   against the graphite 14px other column. *\/\n.et-l--post .cc-comparison td:nth-of-type(1) { font-weight: 600; font-variant-numeric: tabular-nums; }\n.et-l--post .cc-comparison td:nth-of-type(2) { color: var(--graphite); font-size: 14px; }\n.et-l--post .cc-comparison__check { display: inline-block; font-size: 17px; font-weight: 600; line-height: 1; }\n\/* The words a screen reader hears for the check mark. Hidden by clip-path alone, at its natural size: the\n   usual 1px box makes the text overflow its box, which acceptance A4 (rightly) reads as overflowing text. *\/\n.et-l--post .cc-comparison__sr { position: absolute; clip-path: inset(50%); white-space: nowrap; }\n\/* Grouped tables (the library specimen): a group title spans the row above its features. *\/\n.et-l--post .cc-comparison .cc-comparison__group th { padding: var(--s-5) 0 var(--s-2); border-bottom-color: var(--ink); background: transparent; font-weight: 600; text-align: left; }\n.et-l--post .cc-comparison__note { margin: var(--s-3) 0 0; font-size: var(--t-meta-size); line-height: 1.5; color: var(--graphite); }\n.et-l--post .cc-comparison .stack-cta { justify-content: flex-start; margin-top: var(--s-6); }\n\n\/* Small phones: the same steps the rate ledger takes at this width. The answer column widens\n   so \"No siempre\" (the longest answer) stays on one line at 320; the row label wraps instead. *\/\n@media (max-width: 360px) {\n  .et-l--post .cc-comparison thead th:nth-child(3) { width: 30%; }\n  .et-l--post .cc-comparison th, .et-l--post .cc-comparison td { padding-left: 8px; padding-right: 8px; font-size: 14px; }\n  .et-l--post .cc-comparison thead th { font-size: 10px; letter-spacing: 0.06em; }\n  .et-l--post .cc-comparison td:nth-of-type(2) { font-size: 13px; }\n}\n\n@media (min-width: 760px) {\n  .et-l--post .cc-comparison thead th:nth-child(2), .et-l--post .cc-comparison thead th:nth-child(3) { width: 200px; }\n  .et-l--post .cc-comparison th, .et-l--post .cc-comparison td { padding-top: 15px; padding-bottom: 15px; font-size: 16px; }\n  .et-l--post .cc-comparison thead th { padding-top: 0; font-size: var(--t-micro-size); }\n  .et-l--post .cc-comparison td:nth-of-type(2) { font-size: 15px; }\n}\n\n\/* Phase 2: preserve the contact page's form-first grouping and direct routes. *\/\n.et-l--post .cc-contact__layout { display:grid; gap:var(--s-6); align-items:start; }\n.et-l--post :is(.cc-contact__direct,.cc-contact__form) { min-width:0; }\n.et-l--post .cc-contact__form { border:1px solid var(--line); background:var(--warm-white); padding:var(--s-5); }\n.et-l--post .cc-contact__direct > h2 { font:600 var(--t-h3-size)\/1.2 var(--font-display); margin:0 0 var(--s-4); padding:0; }\n.et-l--post .cc-contact__methods { display:grid; gap:var(--s-3); list-style:none; padding:0; margin:0; }\n.et-l--post .cc-contact__methods .cc-link { display:flex; align-items:center; gap:var(--s-4); padding:var(--s-4); min-height:80px; border:1px solid var(--line); background:var(--warm-white); text-decoration:none; }\n.et-l--post .cc-link__copy { display:grid; gap:var(--s-1); min-width:0; }\n.et-l--post .cc-link__icon { display:flex; align-items:center; justify-content:center; width:36px; height:36px; flex:none; }\n.et-l--post .cc-link__icon svg { width:22px; height:22px; }\n.et-l--post .cc-contact__methods .cc-link__label { font:600 15px\/1.45 var(--font-body); overflow-wrap:anywhere; }\n.et-l--post .cc-contact__methods .cc-link__detail { font:400 13px\/1.5 var(--font-body); color:var(--graphite); }\n.et-l--post .cc-contact__access { padding:var(--s-5); border:1px solid var(--line); background:var(--ivory-deep); margin-top:var(--s-4); }\n.et-l--post .cc-contact__access dl { margin:0; display:grid; gap:var(--s-3); }\n.et-l--post .cc-contact__access dl > div { display:flex; justify-content:space-between; gap:var(--s-3); font:500 13px\/1.6 var(--font-body); }\n.et-l--post .cc-contact__access dd { margin:0; text-align:right; color:var(--graphite); }\n.et-l--post .cc-contact__access p { font:400 13px\/1.65 var(--font-body); margin:var(--s-5) 0 0; padding:0; }\n.et-l--post .cc-contact__reservation { padding:var(--s-5); border:1px solid var(--ink); background:var(--warm-white); margin-top:var(--s-4); }\n.et-l--post .cc-contact__reservation h3 { font:600 var(--t-h3-size)\/1.2 var(--font-display); margin:0; padding:0; }\n.et-l--post .cc-contact__reservation p { font:400 14px\/1.65 var(--font-body); margin:var(--s-3) 0 var(--s-4); padding:0; }\n.et-l--post .cc-contact__reservation .btn { display:flex; justify-content:center; width:100%; text-align:center; white-space:normal; padding:16px; min-height:52px; }\n.et-l--post .cc-contact__note { font:400 13px\/1.65 var(--font-body); text-align:center; margin:var(--s-4) 0 0; padding:0; }\n.et-l--post .cc-contact__note a { text-decoration:underline; text-underline-offset:4px; }\n.et-l--post .cc-social { display:grid; grid-template-columns:repeat(5,44px); justify-content:flex-start; gap:var(--s-2); list-style:none; margin:var(--s-5) 0 0; padding:0; }\n.et-l--post .cc-social a { width:44px; height:44px; display:flex; align-items:center; justify-content:center; border:1px solid var(--line); background:var(--warm-white); }\n.et-l--post .cc-contact .cc-social { display:flex; flex-wrap:wrap; justify-content:center; max-width:252px; margin-inline:auto; }\n.et-l--post .cc-social svg { width:18px; height:18px; }\n.et-l--post .cc-form { display:grid; gap:var(--s-5); margin:0; max-width:752px; }\n.et-l--post .cc-form__intro :is(h2,h3) { font:600 var(--t-h3-size)\/1.2 var(--font-display); letter-spacing:-.01em; margin:0; padding:0; text-wrap:balance; }\n.et-l--post .cc-contact .cc-form__intro :is(h2,h3) { font-size:var(--t-h2-size); line-height:1.12; }\n.et-l--post .cc-form__quick { display:flex; flex-wrap:wrap; gap:var(--s-2); list-style:none; margin:var(--s-4) 0 0; padding:0; }\n.et-l--post .cc-form__quick .cc-link { display:flex; align-items:center; gap:var(--s-2); min-height:44px; border:1px solid var(--line); padding:8px 12px; text-decoration:none; font:600 13px\/1.5 var(--font-body); }\n.et-l--post .cc-form__quick .cc-link__icon { width:18px; height:18px; }\n.et-l--post .cc-form__quick .cc-link__icon svg { width:18px; height:18px; }\n@media (hover:hover) { .et-l--post .cc-form__quick .cc-link:hover { background:var(--ivory-deep); border-color:#8D8175; color:var(--ink); } }\n.et-l--post .cc-form__intro p { font:500 15px\/1.65 var(--font-body); color:var(--graphite); margin:var(--s-3) 0 0; padding:0; }\n.et-l--post .cc-form__fields { display:grid; gap:var(--s-5); }\n.et-l--post .cc-field { display:grid; gap:var(--s-2); min-width:0; align-content:start; }\n.et-l--post .cc-field label { font:600 13px\/1.6 var(--font-body); margin:0; padding:0; }\n.et-l--post .cc-field label span { font-weight:400; }\n.et-l--post .cc-field :is(input,select,textarea) { width:100%; min-width:0; border:1px solid var(--line); border-radius:0; background:var(--ivory); color:var(--ink); padding:12px 16px; min-height:52px; font:400 16px\/1.5 var(--font-body); }\n.et-l--post .cc-field ::placeholder { color:var(--graphite); opacity:1; }\n.et-l--post .cc-field textarea { resize:vertical; min-height:128px; }\n.et-l--post .cc-field [aria-invalid=\"true\"] { border-width:2px; border-color:var(--ink); padding:11px 15px; }\n.et-l--post .cc-field__error { margin:0; padding:0; font:500 13px\/1.6 var(--font-body); color:var(--ink); }\n.et-l--post .cc-form :is(.cc-form__status,.cc-form__summary) { margin:0; padding:var(--s-4); border:1px solid var(--ink); font:500 16px\/1.6 var(--font-body); background:var(--ivory-deep); }\n.et-l--post .cc-form [hidden] { display:none; }\n\/* 2026-10-01 (A24): the submit takes the standard .btn padding, line-height and 58px floor. Its own\n   16px\/1.6\/52px measured 53px beside 58px buttons on \/rates\/. *\/\n.et-l--post .cc-form > .btn { justify-self:stretch; justify-content:center; white-space:normal; text-align:center; }\n@media (hover:hover) {\n .et-l--post :is(.cc-contact__methods .cc-link,.cc-social a):hover { border-color:#8D8175; color:var(--ink); background:var(--ivory-deep); }\n}\n@media (min-width:980px) {\n .et-l--post .cc-contact__layout { grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); gap:var(--s-7); }\n .et-l--post .cc-contact__form { padding:var(--s-7); }\n .et-l--post .cc-contact__direct { padding-top:var(--s-3); }\n\n}\n\n@media (min-width:1200px) { .et-l--post .cc-contact .cc-social { max-width:none; gap:var(--s-1); } }\n\n\/* Phase 2: technical media retains its intrinsic ratio. The action supplies detail. *\/\n.et-l--post .cc-detail-section__lead { max-width: 62ch; }\n.et-l--post .cc-detail-section__lead:empty,\n.et-l--post .cc-detail-section .bk-h2:empty { display: none; }\n.et-l--post .cc-detail { margin: var(--s-5) 0 0; }\n.et-l--post .cc-detail__open {\n  display: block; width: 100%; padding: 0;\n  border: 1px solid var(--line); border-radius: 0;\n  background: var(--warm-white); color: var(--ink); cursor: zoom-in;\n}\n.et-l--post .cc-detail__open img { display: block; width: 100%; height: auto; object-fit: contain; }\n.et-l--post .cc-detail__open > span {\n  display: flex; justify-content: space-between; align-items: center; gap: var(--s-4);\n  min-height: 56px; padding: var(--s-4) var(--s-5);\n  border-top: 1px solid var(--line); font-family: var(--font-body);\n  font-size: var(--t-meta-size); font-weight: 600; text-align: left;\n}\n.et-l--post .cc-detail__open:hover > span { background: #8D8175; color: #000; }\n.et-l--post .cc-detail figcaption { margin-top: var(--s-3); font-size: var(--t-meta-size); line-height: 1.55; }\n.et-l--post .cc-detail figcaption:empty { display: none; }\n.et-l--post .cc-detail__original,\n.et-l--post .cc-detail__caption a {\n  display: inline-flex; align-items: center; min-height: 44px;\n  font-size: var(--t-meta-size); font-weight: 600; color: var(--ink);\n  text-decoration: underline; text-underline-offset: 4px;\n}\n.et-l--post .cc-detail__dialog {\n  box-sizing: border-box; width: min(1320px, calc(100vw - 32px));\n  max-width: none; max-height: calc(100dvh - 32px); margin: auto;\n  padding: var(--s-5); border: 1px solid var(--ink); border-radius: 0;\n  background: var(--ivory); color: var(--ink); overflow: auto;\n}\n.et-l--post .cc-detail__dialog::backdrop { background: rgba(0,0,0,.72); }\n.et-l--post .cc-detail__toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-5); }\n.et-l--post .cc-detail__toolbar .btn {\n  min-width: 0; padding-inline: var(--s-4); white-space: normal;\n  line-height: 1.35; text-align: center; justify-content: center;\n}\n.et-l--post .cc-detail__viewport { max-height: calc(100dvh - 240px); overflow: auto; background: var(--warm-white); }\n.et-l--post .cc-detail__viewport img { display: block; width: 100%; max-width: 100%; height: auto; margin: 0; }\n.et-l--post .cc-detail__dialog[data-zoomed] .cc-detail__viewport img { width: auto; max-width: none; }\n.et-l--post .cc-detail__caption { margin-top: var(--s-4); }\n.et-l--post .cc-detail__caption p { margin: 0; font-size: var(--t-meta-size); line-height: 1.55; }\n.et-l--post .cc-detail [hidden] { display: none; }\n.et-l--post .cc-detail__error { margin: var(--s-4) 0 0; font-size: var(--t-body-size); }\n@media (max-width: 600px) {\n  .et-l--post .cc-detail__dialog { padding: var(--s-4); }\n  .et-l--post .cc-detail__toolbar { align-items: stretch; }\n  .et-l--post .cc-detail__toolbar .btn { flex: 1; padding-inline: var(--s-2); letter-spacing: .1em; }\n  .et-l--post .cc-detail__open > span { padding-inline: var(--s-4); }\n}\n\n\/* The source section is a guided walkthrough followed by a planning diagram. *\/\n.et-l--post .cc-detail-section__layout { display: grid; grid-template-columns: minmax(0,.68fr) minmax(0,1.32fr); gap: clamp(32px,5vw,64px); align-items: start; }\n\/* 2026-09-25, first page to ship this component (\/tour\/): base.css's !important section-title size\n   already wins over this font-size, and the 1.1 line-height that rode with it made this the only\n   section title off HOME's 1.04 (acceptance A18 red on staging: 50.6px vs 47.84px at 1440, 30.8 vs\n   29.12 at 390). The heading now takes the shared section-title line-height. *\/\n.et-l--post .cc-detail-section__intro .bk-h2 { font-size: var(--t-h2-size); }\n.et-l--post .cc-detail-section__intro .bk-lead { line-height: 1.65; }\n.et-l--post .cc-detail-section__media { min-width: 0; }\n.et-l--post .cc-detail-section__media .cc-tourvid { left: auto; right: auto; margin: 0; width: 100%; max-width: none; aspect-ratio: 16 \/ 9; }\n.et-l--post .cc-detail-section__media .cc-tourvid iframe { width: 100%; height: 100%; border: 0; display: block; }\n.et-l--post .cc-detail-section__media .cc-yt-facade { padding: 0; }\n.et-l--post .cc-detail__label { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-3); }\n.et-l--post .cc-detail__label h3 { margin: 0; font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.4; }\n.et-l--post .cc-detail__label span { font-family: var(--font-body); font-size: 13px; line-height: 1.5; }\n.et-l--post .cc-detail__label h3:empty,\n.et-l--post .cc-detail__label span:empty { display: none; }\n.et-l--post .cc-detail { margin-top: var(--s-6); }\n.et-l--post .cc-detail:first-child { margin-top: 0; }\n.et-l--post .cc-detail__open { background: transparent; border: 0; }\n.et-l--post .cc-detail__open img { border: 1px solid var(--line); box-sizing: border-box; }\n.et-l--post .cc-detail__open > span { border-top: 0; padding: var(--s-3) 0 0; min-height: 44px; justify-content: flex-start; gap: var(--s-3); }\n.et-l--post .cc-detail__open:hover > span { background: transparent; text-decoration: underline; text-decoration-color: #8D8175; }\n.et-l--post .cc-detail__original { display: none; }\n.et-l--post .cc-detail__error:not([hidden]) + .cc-detail__original { display: inline-flex; }\n@media (max-width: 959px) {\n  .et-l--post .cc-detail-section__layout { grid-template-columns: minmax(0,1fr); gap: var(--s-5); }\n  .et-l--post .cc-detail-section__intro { max-width: 62ch; }\n}\n@media (max-width: 600px) {\n  .et-l--post .cc-detail-section__media .cc-tourvid { width: 100vw; max-width: 100vw; margin-left: calc((100% - 100vw) \/ 2); }\n  .et-l--post .cc-detail__label { flex-wrap: wrap; gap: 4px var(--s-3); }\n}\n\n\/* editing.css \u2014 the podcast page's editing add-on price list, built from\n   HOME's shoot-row family (reference\/home.css, base rule offset ~87052,\n   desktop override offset ~107129). base.css already supplies bk-section,\n   bk-section--tight, container-bk, bk-h2, bk-lead, btn and btn--ghost, so\n   this file adds only what those primitives do not cover: shoot-row,\n   shoot-row__name and shoot-row__price, the three classes editing.html's\n   tier shape actually uses. Every declaration of each is enumerated below\n   (base rule, :hover, the min-width:760px override, and the shared\n   compound font-weight group) \u2014 no other shoot-row-family class\n   (shoot-row--feat, __meta, __flag, __right, __use, __arrow) is touched,\n   since this component's markup never emits them. Every selector scoped\n   to .et-l--post per the project's CSS-specificity rule. *\/\n.et-l--post .shoot-row {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) auto;\n  align-items: center;\n  gap: 4px 16px;\n  border: 1px solid var(--line);\n  background: var(--warm-white);\n  padding: 18px 18px;\n  color: inherit;\n  position: relative;\n  transition: border-color .25s, background .25s, transform .25s;\n}\n.et-l--post .shoot-row:hover {\n  border-color: var(--accent);\n  transform: translateY(-1px);\n}\n@media (min-width: 760px) {\n  .et-l--post .shoot-row {\n    grid-template-columns: minmax(0, 1fr) auto;\n    align-content: start;\n    gap: 0;\n    padding: 28px 24px;\n  }\n  .et-l--post .shoot-row__price {\n    font-size: clamp(28px, 3vw, 34px);\n  }\n}\n\n\/* .shoot-row__name \u2014 HOME's base rule sets font-weight: 500, but a later\n   compound rule (.bk-h2, .hm-hero__title, ..., .shoot-row__name, ... ,\n   sharing a font-weight: 600 !important declaration) wins the cascade\n   regardless of source order, the same trap documented in base.css for\n   .bk-h2. Only the weight that actually renders is transcribed here. *\/\n.et-l--post .shoot-row__name {\n  grid-column: 1;\n  font-family: var(--font-display);\n  font-weight: 600 !important;\n  font-size: clamp(21px, 5.2vw, 25px);\n  line-height: 1.05;\n  display: flex;\n  align-items: baseline;\n  gap: 9px;\n  flex-wrap: wrap;\n}\n.et-l--post .shoot-row__price {\n  font-family: var(--font-body);\n  font-weight: 600;\n  letter-spacing: -0.015em;\n  font-size: clamp(24px, 6.5vw, 30px);\n  line-height: 1;\n}\n\n\/* Keep each tier's description with its price and separate the two choices. *\/\n.et-l--post [data-screen-label=\"editing\"] .shoot-row + .shoot-row {\n  margin-top: 24px;\n}\n.et-l--post [data-screen-label=\"editing\"] .shoot-row__meta {\n  margin: 8px 0 0;\n}\n.et-l--post [data-screen-label=\"editing\"] .shoot-row:not(a):hover {\n  transform: none;\n  border-color: var(--line);\n}\n@media (min-width: 760px) {\n  .et-l--post [data-screen-label=\"editing\"] .btn--block {\n    display: inline-flex;\n    width: auto;\n  }\n}\n\n\/* Phase 2 (owner 2026-09-28, rental LP): \"dollhouse needs to stay on the page\". Round 5, after the\n   owner rejected staging v3's tour (\"horrible design and needs to be redone\") and chose \"HOME's\n   pattern, both kept\": the section IS HOME's tour -- room.css's .space-feat \/ .cc-tourvid \/\n   .cc-yt-facade in the walkthrough layout, full-bleed on phones and the container on desktop,\n   16:9 at every width. This file adds only what a 3D model needs on top of HOME's facade: the\n   centred label, the viewer frame, and the one line that opens the owner's Short under it.\n   The poster is the viewer's own first frame on the section's ivory, so there is no tinted box\n   (A22) and the swap does not jump. Spacing: HOME's declarations or --s-* tokens only. *\/\n.et-l--post .cc-explore__label { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); white-space: nowrap; }\n.et-l--post .cc-explore__start:hover .cc-explore__label,\n.et-l--post .cc-explore__start:focus-visible .cc-explore__label { background: #8D8175; color: var(--black); }\n.et-l--post .cc-explore__frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; opacity: 0; transition: opacity .4s cubic-bezier(.22, 1, .36, 1); }\n.et-l--post .cc-tourvid[data-state=\"ready\"] .cc-explore__frame { opacity: 1; }\n.et-l--post .cc-tourvid[data-state=\"ready\"] .cc-explore__label { display: none; }\n.et-l--post .cc-tourvid[data-state=\"loading\"] .cc-explore__label .arrow { display: none; }\n.et-l--post .cc-explore__more { margin: var(--s-4) 0 0; font-size: var(--t-meta-size); line-height: 1.5; }\n.et-l--post .cc-explore__play { position: relative; color: var(--ink); border-bottom: 1px solid var(--accent); text-decoration: none; }\n\/* v7 review: the line measured 199x17 at 390, under WCAG 2.5.8's 24px. The hit area grows by --s-2 above\n   and below (33px) without moving the line or its underline. *\/\n.et-l--post .cc-explore__play::after { content: \"\"; position: absolute; inset: calc(-1 * var(--s-2)) 0; }\n.et-l--post .cc-explore__play:hover { color: #8D8175; border-color: #8D8175; }\n\/* The Short plays where its line was, vertical, never taller than 80% of the screen. *\/\n.et-l--post .cc-explore__vframe { display: block; width: min(100%, calc(80svh * 9 \/ 16)); aspect-ratio: 9 \/ 16; margin: var(--s-4) auto 0; border: 0; }\n\/* Round 6 (v5 review) shrank the label on phones (11px, .1em, 41px tall) so it hid less of the model.\n   2026-10-01 (A24, owner 2026-09-30 \"it should all be standardized\"): the label is the standard 58px\n   .btn at every width, like every other button on the page. The whole frame stays the tap target. *\/\n\/* Round 10: Matterport's in-place rule on phones (\"the iframe has to cover at least 60% of the screen\",\n   Matterport help, Embed a Matterport 3D Model). Measured on staging at 390x844: 480px (57%) showed its\n   play screen, which leaves the page; 530px (63%) and 620px (73%) played in place. *\/\n@media (max-width: 759px) {\n  .et-l--post .cc-explore .cc-tourvid[data-state] div.cc-yt-facade { aspect-ratio: auto; height: var(--cc-explore-open, 70svh); }\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .cc-explore__frame { transition: none; }\n}\n\n\/* faq.css \u2014 HOME's FAQ accordion (.faq), extracted verbatim from\n   reference\/home.css (offset ~104586-105797, one contiguous block).\n   Every selector scoped to .et-l--post per the project's CSS-specificity\n   rule. Exactly one declaration found for each selector below\n   (enumerated every literal occurrence in reference\/home.css, not just\n   the first match) \u2014 no cascade conflicts.\n\n   The toggle script is inline in scratchpad\/home.html (comment\n   \"FAQ accordion\"), the same file already mined for .specacc__head and\n   .gal-tab \u2014 confirmed by searching for \"faq-q\" before concluding\n   anything, not assumed. faq.html now carries that exact script (click\n   toggle, an initial\/resize\/font-load fit pass named ccFaqFit), brace-\n   doubled for str.format() the same way specacc.html\/gallery.html are. *\/\n.et-l--post .faq {\n  border-top: 1px solid var(--line);\n  margin-top: 16px;\n}\n.et-l--post .faq-item {\n  border-bottom: 1px solid var(--line);\n}\n.et-l--post .faq-q {\n  width: 100%;\n  background: none;\n  border: 0;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 16px;\n  padding: 20px 2px;\n  text-align: left;\n  color: inherit;\n  font-family: var(--font-body);\n  font-size: 15px;\n  font-weight: 600;\n}\n.et-l--post .faq-icon {\n  position: relative;\n  width: 16px;\n  height: 16px;\n  flex: 0 0 auto;\n}\n.et-l--post .faq-icon::before,\n.et-l--post .faq-icon::after {\n  content: \"\";\n  position: absolute;\n  background: var(--accent);\n  transition: transform .35s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .faq-icon::before {\n  top: 50%;\n  left: 0;\n  right: 0;\n  height: 1.5px;\n  transform: translateY(-50%);\n}\n.et-l--post .faq-icon::after {\n  left: 50%;\n  top: 0;\n  bottom: 0;\n  width: 1.5px;\n  transform: translateX(-50%);\n}\n\/* FIX 5: aria-expanded lives on .faq-q (the button that is actually focused\n   and clicked), not on the wrapping .faq-item div \u2014 see faq.html's script. *\/\n.et-l--post .faq-q[aria-expanded=\"true\"] .faq-icon::after {\n  transform: translateX(-50%) scaleY(0);\n}\n\/* A COLLAPSED PANEL MUST LEAVE THE TAB ORDER. Added 2026-09-14.\n\n   `max-height: 0; overflow: hidden` hides a panel visually and does NOTHING to\n   focusability. Measured on the reference page: 4 `<a href>` links inside collapsed\n   `.faq-a` panels matched `:focus-visible`, held live bounding rects, and painted ZERO\n   pixels on focus. A keyboard user tabs into content they cannot see, on every page\n   carrying an FAQ -- SC 2.4.3 and 2.4.7, in a library component. Neither review round\n   caught it until a seat enumerated every focusable node instead of sampling some.\n\n   `visibility: hidden` is the fix that needs no JavaScript: it takes descendants out of\n   the tab order, and the state already lives on the button as `aria-expanded`, so the\n   sibling combinator reads it rather than inventing a second source of truth. The\n   delayed transition keeps the panel visible for the length of the close animation, so\n   the height collapse is still seen. *\/\n.et-l--post .faq[data-cc-disclosure-ready] .faq-q[aria-expanded=\"false\"] + .faq-a {\n  visibility: hidden;\n  transition: max-height .4s cubic-bezier(.4,0,.2,1), visibility 0s linear .4s;\n}\n\n.et-l--post .faq[data-cc-disclosure-ready] .faq-q[aria-expanded=\"true\"] + .faq-a {\n  visibility: visible;\n  transition: max-height .4s cubic-bezier(.4,0,.2,1), visibility 0s;\n}\n\n.et-l--post .faq-a {\n  overflow: hidden;\n  max-height: none;\n  transition: max-height .4s cubic-bezier(.4,0,.2,1);\n}\n.et-l--post .faq-a__in {\n  padding: 0 2px 22px;\n  font-size: 14px;\n  font-weight: 500;\n  color: var(--graphite);\n  line-height: 1.6;\n  max-width: 64ch;\n}\n\/* Rental LP round 4: an answer link was an 18px-tall target. Vertical padding on an inline box\n   enlarges the tap area without moving any line of the answer. *\/\n.et-l--post .faq-a__in a { padding-block: 4px; }\n\n\/* One FAQ heading and a continuous question list; no subtitle\/topic headings. *\/\n.et-l--post .cc-faqgroups-body {min-width:0;display:grid;gap:0;margin-top:var(--s-6)}\n.et-l--post .cc-faqgroups-body > .bk-section {padding:0!important}\n.et-l--post .cc-faqgroups-body > .bk-section > .container-bk {width:100%;margin:0;max-width:none}\n.et-l--post .cc-faqgroups .faq {margin-top:0}\n.et-l--post .cc-faqgroups-body > [data-cc-faq-group] ~ [data-cc-faq-group] .faq {border-top:0}\n@media(min-width:981px){.et-l--post .cc-faqgroups-body {margin-top:var(--s-7)}}\n\n\n\/* HOME-derived gallery controls and responsive photographic composition.\n   Keep the first visible frame dominant and let small filtered sets fill the grid. *\/\n.et-l--post .gal-tabs {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n  margin: 22px 0 16px;\n}\n\/* Task 10 residual FIX 2: a manifest with one genuine category (or none at\n   all) passes tabs as an empty string rather than inventing categories --\n   the wrapping div then renders with no children at all, but still holds\n   its own 22px\/16px margin, leaving an unexplained gap above the photo\n   grid. Chosen fix (simpler of the two options in the brief): a CSS-only\n   :empty rule, over having the component omit the wrapper -- omitting the\n   wrapper needs a conditional in the template that this plain str.format\n   markup has no way to express, where :empty just reads the DOM state\n   that already exists. Same mechanism as offer.css's empty-secondary-\n   action collapse. *\/\n\/* Filters become usable when the component's script initializes. *\/\n.et-l--post [data-gallery]:not([data-gallery-ready]) .gal-tabs,\n.et-l--post .gal-tabs:empty {\n  display: none;\n}\n.et-l--post .gal-tab {\n  font-family: var(--font-body);\n  font-size: var(--t-ui-size);\n  font-weight: 600;\n  letter-spacing: 0.04em;\n  padding: 7px 15px;\n  border: 1px solid var(--line);\n  background: transparent;\n  cursor: pointer;\n  color: var(--ink);\n  transition: background .2s, color .2s, border-color .2s;\n}\n.et-l--post .gal-tab.is-sel {\n  background: var(--accent);\n  color: var(--ivory);\n  border-color: var(--accent);\n}\n\n\/* HOME mobile keeps the gallery as equal two-column peers. The script\n   marks filtered figures hidden, so desktop lead selectors follow visible order. *\/\n.et-l--post .gal-grid {\n  display: grid;\n  grid-template-columns: repeat(2, minmax(0, 1fr));\n  gap: var(--s-2) var(--s-3);\n}\n.et-l--post .gal-grid figure {\n  margin: 0;\n  min-width: 0;\n  min-height: 0;\n  overflow: hidden;\n  aspect-ratio: 3\/2;\n}\n\/* 2026-09-28 (owner: \"some are okay to be cropped but others not\"): a registered portrait frame\n   spans two rows (~0.73), so a standing person is not cut at the knees by a 3:2 cell (it showed\n   44% of its height). images.py stamps data-frame-orientation on every registered <img>; dense\n   packing fills the neighbour column. HOME's gallery has no portrait frame, so it is unchanged.\n   Round 6 (A23): `aspect-ratio: auto` let the photo's own height (w\/0.67) set the two rows it spans,\n   so those rows grew and showed 19px\/28px gutters beside HOME's 8px. A 3:4 ratio contributes less\n   than two 3:2 rows plus the gap, and stretch fills exactly that area. Both axes stretch: with only\n   align-self, the ratio set the WIDTH from the stretched height (179px in a 173px column, v7 review). *\/\n.et-l--post .gal-grid { grid-auto-flow: dense; }\n.et-l--post .gal-grid > figure:has(img[data-frame-orientation=\"portrait\"]) { grid-row: span 2; aspect-ratio: 3 \/ 4; align-self: stretch; justify-self: stretch; }\n.et-l--post .gal-open {\n  display: block;\n  width: 100%;\n  height: 100%;\n  min-height: 44px;\n  padding: 0;\n  border: 0;\n  border-radius: 0;\n  background: transparent;\n  color: inherit;\n  cursor: zoom-in;\n  overflow: hidden;\n}\n.et-l--post .gal-open:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: -4px;\n  box-shadow: inset 0 0 0 5px var(--ink);\n}\n\/* Four desktop columns fit a 2x2 lead and four supports. An 8px row gutter\n   with a 12px column gutter keeps every cell exactly 3:2, including the lead.\n   Three frames use three columns; one or two use only two columns. *\/\n@media (min-width: 760px) {\n  .et-l--post .gal-grid {\n    grid-template-columns: repeat(4, minmax(0, 1fr));\n  }\n  .et-l--post .gal-grid:not(.gal-grid--rail) > figure:nth-child(1 of figure:not([hidden])) {\n    grid-column: span 2;\n    grid-row: span 2;\n  }\n  \/* The direct :not([hidden]) also invalidates :has() when a filter changes;\n     putting it only inside the of-clause left stale column counts in Chromium. *\/\n  .et-l--post .gal-grid:has(> figure:not([hidden]):nth-child(3 of figure:not([hidden])):nth-last-child(1 of figure:not([hidden]))) {\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n  }\n  .et-l--post .gal-grid:not(.gal-grid--rail):not(:has(> figure:not([hidden]):nth-child(3 of figure:not([hidden])))) {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n  .et-l--post .gal-grid:not(:has(> figure:not([hidden]):nth-child(3 of figure:not([hidden])))) > figure {\n    grid-row: auto;\n  }\n}\n\/* Two frames are peers; a single frame retains the full-width lead treatment. *\/\n.et-l--post .gal-grid > figure:nth-child(1 of figure:not([hidden])):nth-last-child(2 of figure:not([hidden])) {\n  grid-column: auto;\n  grid-row: auto;\n}\n.et-l--post .gal-grid img {\n  display: block;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  transition: transform .9s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .gal-grid figure:hover img {\n  transform: scale(1.05);\n}\n\/* gallery.html updates hidden and inline display together. Hidden also defines\n   which figures take part in the layout selectors above. *\/\n.et-l--post .gal-grid figure[hidden] {\n  display: none;\n}\n\n\/* One native modal viewer per architectural gallery. It reads every source\n   figure in DOM order, so the expanded sequence continues across filters. *\/\nhtml.gal-lightbox-open:has(.et-l--post .gal-lightbox[open]),\nbody.gal-lightbox-open:has(.et-l--post .gal-lightbox[open]) {\n  overflow: hidden !important;\n  overscroll-behavior: none;\n}\nhtml.gal-lightbox-open:has(.et-l--post .gal-lightbox[open]) {\n  scrollbar-gutter: stable;\n}\n.et-l--post .gal-lightbox {\n  position: fixed;\n  inset: 0;\n  width: 100%;\n  max-width: none;\n  height: 100%;\n  max-height: none;\n  margin: 0;\n  padding: 0;\n  border: 0;\n  border-radius: 0;\n  background: rgba(11,10,9,.96);\n  color: var(--ivory);\n  overflow: hidden;\n}\n.et-l--post .gal-lightbox[open] {\n  display: block;\n}\n.et-l--post .gal-lightbox::backdrop {\n  background: rgba(11,10,9,.92);\n}\n.et-l--post .gal-lightbox__stage {\n  box-sizing: border-box;\n  display: grid;\n  place-items: center;\n  width: 100%;\n  min-height: 100svh;\n  min-height: 100dvh;\n  padding: max(56px,env(safe-area-inset-top)) max(64px,env(safe-area-inset-right)) max(56px,env(safe-area-inset-bottom)) max(64px,env(safe-area-inset-left));\n  overscroll-behavior: contain;\n  touch-action: pan-y;\n}\n.et-l--post .gal-lightbox figure {\n  display: grid;\n  place-items: center;\n  width: 100%;\n  height: 100%;\n  margin: 0;\n  overflow: hidden;\n  aspect-ratio: auto;\n}\n.et-l--post .gal-lightbox img {\n  display: block;\n  width: auto;\n  height: auto;\n  max-width: calc(100vw - 128px);\n  max-height: calc(100svh - 112px);\n  max-height: calc(100dvh - 112px);\n  object-fit: contain;\n  user-select: none;\n  -webkit-user-drag: none;\n}\n.et-l--post .gal-lightbox__close,\n.et-l--post .gal-lightbox__nav {\n  position: fixed;\n  z-index: 1;\n  display: grid;\n  place-items: center;\n  width: 48px;\n  height: 48px;\n  min-height: 48px;\n  padding: 0;\n  border: 1px solid rgba(249,240,224,.55);\n  border-radius: 0;\n  background: rgba(11,10,9,.72);\n  color: var(--ivory);\n  font-family: var(--font-body);\n  font-size: var(--t-h3-size);\n  line-height: 1;\n  cursor: pointer;\n}\n.et-l--post .gal-lightbox__close:hover,\n.et-l--post .gal-lightbox__nav:hover {\n  border-color: var(--ivory);\n  background: var(--ivory);\n  color: var(--ink);\n}\n.et-l--post .gal-lightbox__close:focus-visible,\n.et-l--post .gal-lightbox__nav:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: 3px;\n}\n.et-l--post .gal-lightbox__close {\n  top: max(12px,env(safe-area-inset-top));\n  right: max(12px,env(safe-area-inset-right));\n  font-size: var(--t-numeral-size);\n}\n.et-l--post .gal-lightbox__prev {\n  top: 50%;\n  left: max(12px,env(safe-area-inset-left));\n  transform: translateY(-50%);\n}\n.et-l--post .gal-lightbox__next {\n  top: 50%;\n  right: max(12px,env(safe-area-inset-right));\n  transform: translateY(-50%);\n}\n.et-l--post .gal-lightbox__status {\n  position: fixed;\n  bottom: max(16px,env(safe-area-inset-bottom));\n  left: 50%;\n  transform: translateX(-50%);\n  padding: 8px 12px;\n  background: rgba(11,10,9,.72);\n  color: var(--ivory);\n  font-family: var(--font-body);\n  font-size: var(--t-ui-size);\n  font-weight: 600;\n  line-height: 1;\n  white-space: nowrap;\n}\n@media (max-width: 759px) {\n  .et-l--post .gal-lightbox__stage {\n    padding-right: 12px;\n    padding-left: 12px;\n  }\n  .et-l--post .gal-lightbox img {\n    max-width: calc(100vw - 24px);\n    max-height: calc(100svh - 112px);\n    max-height: calc(100dvh - 112px);\n  }\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .gal-grid img {\n    transition: none;\n  }\n}\n\n\/* HOME's social feed is an edge-to-edge square grid: four visible tiles on\n   mobile, eight on desktop. The linked images remain native Instagram posts. *\/\n.et-l--post [data-gallery]:has(.gal-grid > figure > a[href*=\"instagram.com\/\"]):not(:has(.gal-grid > figure > img, .gal-grid > figure > .gal-open, .gal-grid > figure > a:not([href*=\"instagram.com\/\"]))) .container-bk {\n  width: 100%;\n}\n.et-l--post [data-gallery] .bk-h2:empty { display: none; }\n.et-l--post [data-gallery] .gal-grid:empty { display: none; }\n\/* The feed's vertical spacing is a derived condition (spacing.py, base.css bk-gap-*):\n   standard or related space above it, flush against the map or footer below it.\n   Owner 2026-09-24 retired the 2026-09-22 rule that zeroed the section above the\n   feed -- \"I didn't ask for no space I asked for standard normal looking.\" *\/\n.et-l--post [data-gallery]:has(.cc-live-feed--instagram) .container-bk {\n  display: none;\n}\n.et-l--post .cc-live-feed--instagram,\n.et-l--post .cc-live-feed--instagram #sb_instagram {\n  width: 100% !important;\n  max-width: none !important;\n  padding: 0 !important;\n}\n\/* Owner 2026-09-22: Smash Balloon's own grid wrapper carries `padding: 12px 0`, which\n   is the ivory strip that survived above the map after the section paddings went to\n   zero. Measured on the live page: last tile bottom 6780, feed section bottom 6792.\n   Zeroing the wrapper, not the items, leaves the tiles' own edges untouched. *\/\n.et-l--post .cc-live-feed--instagram #sbi_images {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n.et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) {\n  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;\n  gap: 0;\n  margin-top: 0;\n}\n.et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) > figure {\n  grid-area: auto !important;\n  aspect-ratio: 1;\n  border: 0;\n}\n.et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) > figure > a {\n  display: block;\n  height: 100%;\n}\n.et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) img {\n  height: 100%;\n  object-fit: cover;\n  transform: none;\n}\n@media (max-width: 759px) {\n  .et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) > figure:nth-of-type(n+5) {\n    display: none;\n  }\n  \/* Smash Balloon owns the live-feed markup, so the static figure rule above\n     cannot control its responsive count. Keep the approved HOME contract\n     explicit at the rendered-item level: eight items may load, only the first\n     four participate in the mobile layout. *\/\n  .et-l--post .cc-live-feed--instagram #sb_instagram .sbi_item:nth-child(n+5) {\n    display: none !important;\n  }\n}\n@media (min-width: 760px) {\n  .et-l--post .gal-grid:has(> figure > a[href*=\"instagram.com\/\"]):not(:has(> figure > img, > figure > .gal-open, > figure > a:not([href*=\"instagram.com\/\"]))) {\n    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;\n  }\n}\n\n\/* HOME gallery closing card, lifted from the live reference. *\/\n.et-l--post .gal-cta {\n  grid-column: 1 \/ 3;\n  background: var(--ivory);\n  border: 1px solid var(--line);\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  text-align: center;\n  gap: 14px;\n  padding: 34px 22px;\n}\n.et-l--post .gal-cta h3 {\n  font-family: var(--font-display);\n  font-weight: 600;\n  line-height: 1.04;\n  margin: 0;\n}\n.et-l--post .gal-cta p {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  letter-spacing: 0.02em;\n  color: var(--graphite);\n  margin: 0;\n}\n.et-l--post .gal-cta h3 {\n  font-weight: 600 !important;\n}\n\/* The card title sits on one line at every width (owner 2026-10-04: \"Your Shoot Belongs Here fits on one line on all\n   breakpoints\"). HOME's size where it fits; narrower cards scale it to the card from its character count\n   (--cta-chars, written by gallery_closing.py; 0.53em covers CC Bodoni 600's widest measured title, 0.515em\/char).\n   !important: the theme sets every h3 to 16px !important below 325px. *\/\n.et-l--post .gal-cta { container-type: inline-size; }\n.et-l--post .gal-cta h3 {\n  max-width: none;\n  white-space: nowrap;\n  font-size: min(clamp(24px, 6vw, 32px), calc(100cqi \/ (var(--cta-chars, 16) * 0.53))) !important;\n}\n\n\/* The titled card's rhythm (owner 2026-10-04: \"the spacing in your shoot belongs here ... above title, below title and\n   below cta\"). HOME's closing rhythm (close.css): the title hugs its line, the action sits apart, and the card's top\n   and bottom match. Measured: the theme's h3 {padding-bottom: 10px} pushed the title 27px off its line while the\n   button sat 18px under it. Titled cards only: the Christmas set descriptions reuse .gal-cta without a title. *\/\n.et-l--post .gal-cta:has(> h3) { padding-block: var(--s-6); gap: 0; }\n.et-l--post .gal-cta:has(> h3) > h3 { padding-bottom: 0; }\n.et-l--post .gal-cta:has(> h3) > p { margin: var(--s-2) 0 var(--s-5); }\n\n\/* Keep translated CTA labels inside the card at 320px. *\/\n.et-l--post .gal-cta .btn {\n  max-width: 100%;\n  white-space: normal;\n  justify-content: center;\n}\n\n\/* Phase 2 \u00b7 Set rail -- owner 2026-09-30, Christmas: \"too much scrolling for mobile ... use all the\n   photos ... best in class\". Opt-in with content.layout = \"rail\", so HOME's grid above is unchanged\n   (its two lead\/column-count rules exclude .gal-grid--rail). One set's photos: the widest frame leads\n   at HOME's 3:2, every other frame sits in one swipe row at its native ratio, so nothing is cropped and\n   no frame is repeated to fill a grid. Mechanics are the usecases phone carousel's (snap, contained\n   overscroll, no scrollbar); gutters are the gallery's own tokens. No counter; a tap opens the shared\n   viewer. Arrows were left out on 2026-09-30 (the peek was to be the cue) and added on 2026-10-02 (owner:\n   \"add arrows to the sets carousel so it looks like you can scroll\"), see .gal-railnav below. Phones stack lead, row and card; from 920px (the reviews desktop step) the lead and the\n   row share one height side by side. *\/\n.et-l--post .gal-grid.gal-grid--rail {\n  --gal-rail-h: clamp(300px, 90vw, 440px);\n  grid-template-columns: minmax(0, 1fr);\n  grid-auto-flow: row;\n}\n.et-l--post .gal-grid.gal-grid--rail > figure {\n  grid-column: auto;\n  grid-row: auto;\n}\n\/* Under a row the set's card is the chapter's closing line, not a second box: HOME's card type and\n   gap, left-aligned on the section ground. *\/\n.et-l--post .gal-grid--rail > .gal-cta {\n  grid-column: 1 \/ -1;\n  padding: 0;\n  border: 0;\n  background: none;\n  align-items: flex-start;\n  text-align: left;\n}\n.et-l--post .gal-grid--rail > .gal-cta h3 {\n  max-width: none;\n}\n\/* The set's description reads as a paragraph, so it takes .bk-lead's body setting instead of the\n   card's 13px note. *\/\n.et-l--post .gal-grid--rail > .gal-cta p {\n  font-size: var(--t-body-size);\n  font-weight: 500;\n  letter-spacing: normal;\n  line-height: 1.6;\n  max-width: 56ch;\n  text-wrap: pretty;\n}\n.et-l--post .gal-rail {\n  display: flex;\n  gap: var(--s-3);\n  min-width: 0;\n  overflow-x: auto;\n  overscroll-behavior-x: contain;\n  scroll-snap-type: x mandatory;\n  scroll-behavior: smooth;\n  scrollbar-width: none;\n  -webkit-overflow-scrolling: touch;\n}\n.et-l--post .gal-rail::-webkit-scrollbar {\n  display: none;\n}\n.et-l--post .gal-rail:focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 3px;\n}\n\/* Arrows (owner 2026-10-02: \"add arrows to the sets carousel so it looks like you can scroll\"; this\n   reverses the 2026-09-30 peek-only ruling). They share the rail's grid cell instead of wrapping it,\n   centred on its height, and wear the shared viewer's square arrow; hover takes the brand taupe. *\/\n.et-l--post .gal-grid--rail > .gal-rail,\n.et-l--post .gal-grid--rail > .gal-railnav {\n  grid-row: 2;\n  grid-column: 1;\n}\n.et-l--post .gal-railnav {\n  z-index: 1;\n  align-self: center;\n  display: flex;\n  justify-content: space-between;\n  padding: 0 var(--s-2);\n  pointer-events: none;\n}\n.et-l--post .gal-railnav__btn {\n  display: grid;\n  place-items: center;\n  width: 48px;\n  height: 48px;\n  min-height: 48px;\n  padding: 0;\n  border: 1px solid rgba(249,240,224,.55);\n  border-radius: 0;\n  background: rgba(11,10,9,.72);\n  color: var(--ivory);\n  font-family: var(--font-body);\n  font-size: var(--t-h3-size);\n  line-height: 1;\n  cursor: pointer;\n  pointer-events: auto;\n}\n.et-l--post .gal-railnav__btn[hidden] {\n  display: none;\n}\n.et-l--post .gal-railnav__next {\n  margin-left: auto;\n}\n.et-l--post .gal-railnav__btn:hover {\n  border-color: #8D8175;\n  background: #8D8175;\n  color: #000;\n}\n.et-l--post .gal-railnav__btn:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: -5px;\n}\n.et-l--post .gal-grid--rail .gal-rail > figure {\n  flex: none;\n  height: var(--gal-rail-h);\n  aspect-ratio: auto;\n  scroll-snap-align: start;\n}\n.et-l--post .gal-grid--rail .gal-rail img {\n  width: auto;\n  max-width: none;\n  height: 100%;\n}\n\/* A wide frame inside the row takes the row's full width at its own ratio instead of the row's\n   height, which on a phone would make it wider than the screen. *\/\n.et-l--post .gal-grid--rail .gal-rail > figure:has(img[data-frame-orientation=\"landscape\"]) {\n  flex: 0 0 100%;\n  height: auto;\n  align-self: center;\n}\n.et-l--post .gal-grid--rail .gal-rail > figure:has(img[data-frame-orientation=\"landscape\"]) img {\n  width: 100%;\n  height: auto;\n}\n@media (min-width: 920px) {\n  .et-l--post .gal-grid.gal-grid--rail {\n    grid-template-columns: auto minmax(0, 1fr);\n    align-items: start;\n  }\n  .et-l--post .gal-grid--rail > .gal-cta {\n    display: grid;\n    grid-template-columns: minmax(0, 1fr) auto;\n    column-gap: var(--s-6);\n    align-items: center;\n  }\n  .et-l--post .gal-grid--rail > .gal-cta .btn {\n    grid-column: 2;\n    grid-row: 1 \/ span 2;\n  }\n  .et-l--post .gal-grid.gal-grid--rail > figure {\n    height: var(--gal-rail-h);\n  }\n  .et-l--post .gal-grid--rail > .gal-rail,\n  .et-l--post .gal-grid--rail > .gal-railnav {\n    grid-row: 1;\n    grid-column: 2;\n  }\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .gal-rail {\n    scroll-behavior: auto;\n  }\n}\n\n\/* hero.css \u2014 HOME's above-fold hero band (.hm-herosec > .hm-hero > .hm-hero__in),\n   extracted from reference\/home.css. Exact byte offsets are in task-3-report.md.\n   Every selector is scoped to .et-l--post per the project's CSS-specificity rule. *\/\n\n\/* F1 fix \u2014 the ~145px opaque white band above the hero (Divi's default section\n   top padding, stacked on top of HOME's own nav-clearance padding below).\n   HOME's own fix, copied verbatim (reference\/home.css offset ~52457). *\/\n#page-container .et-l--post .et_pb_section.et_pb_section_0{padding-top:0!important}\n\n\/* The fixed navigation overlays the media. A former 79px padding-top created an\n   empty beige band between the header and video on both breakpoints. *\/\n.et-l--post .hm-herosec {\n  position: relative !important;\n  padding-top: 0 !important;\n}\n.et-l--post .hm-herosec .et_pb_row,\n.et-l--post .hm-herosec .et_pb_column,\n.et-l--post .hm-herosec .et_pb_code,\n.et-l--post .hm-herosec .et_pb_code_inner {\n  position: static !important;\n}\n\n\/* .hm-hero \u2014 the image band. HOME ships TWO bare .hm-hero declarations\n   at equal specificity, neither !important (offset ~55043 and ~79831) \u2014\n   the later one wins the whole rule (min-height:clamp(..., 800px) beats the\n   earlier clamp(..., 760px); position\/display\/align-items\/overflow\/\n   background have no earlier competitor at all). Fix round 1 correction:\n   the first pass here transcribed the LOSING (earlier, 760px-only)\n   declaration and missed that the winner makes `.hm-hero` a flex container\n   that bottom-aligns its content (`display:flex; align-items:flex-end`) \u2014\n   without that, `.hm-hero__in` falls into ordinary block flow and pins to\n   the TOP of the image, which is also where `.hm-scrim` is weakest (see\n   the F4 note on `.hm-scrim` below).\n\n   Two further narrow-viewport .hm-hero min-height overrides exist,\n   found on the same re-check: `@media(max-width:479px)` and\n   `@media(max-width:359px)`, compensating min-height for the mobile\n   header at very small viewports. Transcribed as their own media blocks\n   until 2026-10-02, when the first paint became the full screen (see the\n   note on `.hm-hero` below).\n\n   Beyond the winning declaration, two properties are still added, both\n   still needed because this component's template nests `.hm-scrim` INSIDE\n   `.hm-hero` and paints the photo via CSS background-image rather than\n   HOME's <video>, per the reasoning below:\n     - the winning declaration's own `position: relative` already covers\n       the nested-scrim positioning-context need described in the previous\n       revision of this comment \u2014 no separate addition required there\n       anymore.\n     - background-size\/position\/repeat \u2014 reproducing the <video>'s\n       object-fit:cover \/ object-position:center behaviour for a CSS\n       background-image instead of a video element. *\/\n\/* Owner 2026-10-02 (\"flickers on tour, home page, etc.\"): the first paint is the full first screen.\n   HOME's clamp(480px, 72svh, 800px) and its phone overrides (100svh - 149px \/ 164px, room for the\n   trust strip the Crown hero retired) were never the final height: home_fold.js stretched the hero to\n   the screen at DOMContentLoaded, so every page painted a short hero, then jumped (filmed at 390x844:\n   Home 0.91 -> 1.13 s, Book 0.76 -> 1.04 s, Christmas 0.70 -> 1.05 s). The hero sits at the top of the\n   page under the overlaid nav, so 100svh is the height the script arrives at; the script still grows\n   the hero when its copy is taller than a short screen. *\/\n.et-l--post .hm-hero {\n  position: relative;\n  min-height: 100svh;\n  display: flex;\n  align-items: flex-end;\n  overflow: hidden;\n  background: transparent;\n  background-size: cover;\n  background-position: center center;\n  background-repeat: no-repeat;\n}\n.et-l--post .hm-bgpic {\n  position:absolute;\n  inset:0;\n  z-index:0;\n}\n.et-l--post .hm-bgpic img {\n  display:block;\n  width:100%;\n  height:100%;\n  object-fit:cover;\n  object-position:center;\n}\n\/* Owner 2026-10-02: \"I do not want any poster\". A video hero paints nothing but the video, so its\n   ground is ink until the first frame: the overlaid nav and the hero copy are ivory, and on the page's\n   ivory they would vanish until the video arrives. The phone video opens on a black title card. *\/\n.et-l--post .hm-hero:has(.hm-bgvid) {\n  background-color: var(--ink);\n}\n\n\/* A light upper veil preserves the photograph. The stronger scrim follows the\n   content block below, so a long translation cannot rise above its protection.\n   Fixed viewport-percentage stops failed at the first glyph in short viewports;\n   see the fresh minimum-contrast red run in implementation\/contrast\/. *\/\n.et-l--post .hm-scrim {\n  position: absolute;\n  inset: 0;\n  z-index: 1;\n  pointer-events: none;\n  background: linear-gradient(180deg, rgba(28,20,14,.18), transparent 65%);\n}\n\n\/* .hm-hero__in \u2014 the content column, above the scrim. *\/\n.et-l--post .hm-hero__in {\n  position: relative;\n  z-index: 2;\n  width: min(1180px, 92vw);\n  margin: 0 auto;\n  padding: 0 0 clamp(40px, 7vw, 72px);\n  color: var(--ivory);\n}\n\n\/* Fade starts above the text and reaches its contrast floor at the first line.\n   It spans the section, never a tinted card behind the copy. *\/\n.et-l--post .hm-hero__in::before {\n  content: \"\";\n  position: absolute;\n  z-index: -1;\n  left: 50%;\n  transform: translateX(-50%);\n  width: 100vw;\n  top: -240px;\n  bottom: 0;\n  pointer-events: none;\n  background: linear-gradient(180deg, rgba(28,20,14,0) 0,\n    rgba(28,20,14,.70) 240px, rgba(28,20,14,.85) 100%);\n}\n\n\/* .hm-hero__title \u2014 HOME's H1. Three winning declarations are reconciled\n   here: the bare `.et-l--post h1` rule (font-family \/ line-height base), the\n   class-specific `.hm-hero__title` rule (higher specificity than the bare h1\n   rule, so its line-height \/ letter-spacing \/ max-width win instead), and the\n   compound `!important` weight override HOME shares with `.bk-h2` and others\n   (font-weight:600). HOME's live H1 also carries an inline font-size override\n   (clamp(34px, 9vw, 60px)) that beats the class rule's own clamp(36px, 7.4vw, 66px)\n   by specificity \u2014 that smaller, actually-rendered clamp is transcribed here\n   directly so the component does not depend on a per-page inline style. *\/\n.et-l--post .hm-hero__title {\n  font-family: var(--font-display);\n  font-weight: 600 !important;\n  font-size: var(--t-hero-size);\n  line-height: var(--t-hero-lh);\n  letter-spacing: var(--t-hero-ls) !important;\n  max-width: none;\n  color: var(--ivory);\n  margin: 0;\n  padding: 0;\n  text-wrap: balance;\n  overflow-wrap: break-word;\n}\n\/* Owner 2026-10-03: \"3 words sitting on 2 looks weird\". A title may name its phone lines (manifest\n   `h1_lines`); below 768px each phrase is its own line, so lines break where phrases end and widen downward.\n   A line still wraps inside itself on the narrowest phones, so nothing can overflow. *\/\n@media (max-width: 767px) {\n  .et-l--post .hm-hero__line { display: block; }\n}\n.et-l--post .hm-hero__title em {\n  font-style: italic;\n  font-weight: 500;\n}\n\n\/* .hm-hero__sub *\/\n.et-l--post .hm-hero__sub {\n  font-family: var(--font-body);\n  font-size: clamp(14px, 3.6vw, 18px);\n  font-weight: 500;\n  opacity: 0.9;\n  \/* Owner 2026-10-01, \"still not tight enough ... title to subtitle\": --s-2 (desktop --s-3), down from\n     HOME's clamp(22px, 4vw, 32px). Ink gap measured on staging at 390: 33px -> 19px.\n     padding: 0 because the theme lifts `p{padding-bottom:1em}` only for the LAST paragraph; once the\n     reviews line followed the subtitle it gained 14px of invisible padding (tests\/test_hero_proof.py). *\/\n  margin: var(--s-2) 0 0;\n  padding: 0;\n  max-width: 60ch;\n  line-height: 1.5;\n  \/* 2026-09-30: with both prices in the subtitle, Christmas ended its paragraph on \"24.\" alone. *\/\n  text-wrap: pretty;\n}\n\n\/* --- Ruling C2 \/ SYSTEM_ADDITIONS ---------------------------------------\n   hm-hero__kicker, hm-hero__meta and hm-hero__alt do not exist on HOME \u2014\n   measured, not assumed. Spec 5.1 requires a kicker, a delimited meta list\n   (the F3 fix) and a secondary link, so per D7 they are added to the system\n   here rather than hand-authored on a page. Recorded in SYSTEM.md. *\/\n\n\/* .hm-hero__kicker \u2014 NOT IMPLEMENTED, deliberately. 2026-09-14.\n\n   Spec 5.1 requires a hero kicker; this rule styled one, SYSTEM_ADDITIONS registered\n   it, and hero.html never emitted it. Found by tests\/test_additions_render.py.\n\n   Resolved by dropping it rather than building it, and the argument FOR building it is\n   real enough to record: HOME ships `.hm-hero__eyebrow`, so the treatment is this\n   brand's own hero vocabulary rather than an imported trope, and nothing in\n   direction.json forbids a single kicker. Three things outweigh that.\n\n   1. It would be an INTRODUCTION, not a restoration. The class has matched zero\n      elements for the life of the system, so emitting it now adds a new visible\n      element to the top of every page this system builds. Dropping it changes no\n      pixel anywhere.\n   2. No kicker copy has ever been authored. Across every manifest and sample in the\n      system's history the only values that existed were the literal \"x\", in two unit\n      test fixtures. The obvious content is also redundant: the H1 reads \"Podcast\n      Studio Miami\", so a kicker reading \"PODCAST STUDIO\" repeats the title, which is\n      the specific thing that makes an eyebrow read as generated.\n   3. UBIQUITY INVERTS AT SYSTEM SCALE. direction.json's ban and antislop's\n      `eyebrow-on-every-section` both count eyebrows WITHIN a page, and a hero kicker\n      is one section of eleven, so both would pass. But it would render on 54 of 54\n      pages: total ubiquity across the site, invisible to a per-page check. An element\n      that is voice on HOME's single hero becomes grammar on fifty-four of them.\n\n   WHAT WOULD REVERSE THIS: authored kicker copy that says something the H1 does not --\n   a different term, a qualifier, a proof point. At that moment it stops being scaffold\n   and the argument in (2) disappears. Add the slot then, and put the render in front\n   of the owner at 390x844 first, because it changes every page's first screen. *\/\n\/* .hm-hero__meta \u2014 F3 fix: the meta placeholder renders as real <li>\n   elements here, visually delimited with the same \"\u25c6\" glyph HOME already\n   uses to separate .hm-marquee__item entries (see marquee.css), recoloured\n   for the dark hero band instead of the light marquee band.\n\n   Fix round 3, FIX 3: three items (each 9-26 characters) plus two \"\u25c6\"\n   separators (each with 1.4em of left margin) cannot fit one line at\n   390px alongside the 0.7em side padding per item. The row used to wrap\n   with the separator still glued to the end of the previous line's last\n   item, so a \"\u00b7\" dangled at the right edge with the final item stranded,\n   indented, alone on line two. Below the same 479px breakpoint this\n   component already uses for the hero's own min-height (see `.hm-hero`\n   above), the media query below stacks the items vertically instead of\n   wrapping them horizontally: no wrap point can ever land mid-row, so no\n   separator can ever dangle, regardless of how long any one item's text\n   is. The \"\u25c6\" glyph is dropped at that breakpoint (a vertical list\n   doesn't need an inline separator) rather than rotated to sit at the\n   end of a line, which would just relocate the same risk. *\/\n.et-l--post .hm-hero__meta {\n  display: flex;\n  flex-wrap: wrap;\n  list-style: none;\n  margin: clamp(16px, 3vw, 22px) 0 0;\n  padding: 0;\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--ivory);\n  opacity: 0.92;\n}\n.et-l--post .hm-hero__meta li {\n  padding: 0 0.7em;\n}\n.et-l--post .hm-hero__meta li:first-child {\n  padding-left: 0;\n}\n.et-l--post .hm-hero__meta li:not(:last-child)::after {\n  content: \"\u25c6\";\n  font-size: 0.4em;\n  vertical-align: middle;\n  margin-left: 1.4em;\n  color: var(--ivory);\n  opacity: 0.6;\n}\n@media (max-width: 479px) {\n  .et-l--post .hm-hero__meta {\n    flex-direction: column;\n    align-items: flex-start;\n    gap: 6px;\n  }\n  .et-l--post .hm-hero__meta li {\n    padding: 0;\n  }\n  .et-l--post .hm-hero__meta li:not(:last-child)::after {\n    content: none;\n  }\n}\n\n\/* .hm-hero__reviews \u2014 Crown, owner 2026-09-30. The trust strip under the hero is retired; its\n   review proof moves INTO the hero, directly under the subtitle (the prices live in the subtitle\n   itself). Owner: reviews \"below the studio rates so its not so prominent on the top\", then \"fix\n   the spacing below the subtitle and the google reviews ... make it tighter\".\n\n   Spacing is proximity: the subtitle (the claim) and this line (who vouches for it) are one group,\n   the buttons are the next. Owner 2026-10-01 asked for all three gaps tighter; measured as INK gaps\n   (letters to letters, not boxes) at 390 they went 33\/36\/32px -> 19\/12\/18px: title->subtitle --s-2,\n   subtitle->reviews --s-1, reviews->buttons --s-4 (desktop --s-3\/--s-2\/--s-5). Study and red run:\n   Documents\/2026-09-30_trust-strip-redesign\/build\/spacing-r2\/ and build\/redrun\/.\n\n   Owner 2026-10-01: \"remove the link leading out of our site to google for the hero\". The line is\n   plain text: an unclassed <span> takes the link's place with the link's own inline-flex box, so\n   every letter stays where the owner approved it (making the <p> itself the flex row measured\n   0.9px closer to the subtitle). No underline, hover, focus ring or tap target: nothing here is\n   clickable. Stars are decorative (the label says \"five-star\"), so they are aria-hidden.\n\n   Critique 2026-10-01: at 600 the label read brighter than the subtitle (500), against the owner's\n   \"not so prominent\", and the Spanish label wrapped at 360px, stranding \"Google\". Weight 500 and\n   1px star tracking fit it on one line from 360px (EN from 320px); below that the whole label\n   drops under the stars instead of breaking mid-phrase. *\/\n.et-l--post .hm-hero__reviews {\n  margin: var(--s-1) 0 0;\n  padding: 0;\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  line-height: 1.4;\n  letter-spacing: 0.01em;\n  color: var(--ivory);\n}\n.et-l--post .hm-hero__reviews > span {\n  display: inline-flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: var(--s-1) var(--s-2);\n}\n@media (min-width: 760px) {\n  .et-l--post .hm-hero__sub {\n    margin-top: var(--s-3);\n  }\n  .et-l--post .hm-hero__reviews {\n    margin-top: var(--s-2);\n  }\n}\n.et-l--post .hm-hero__stars {\n  font-size: var(--t-ui-size);\n  letter-spacing: 1px;\n  line-height: 1;\n}\n.et-l--post .hm-hero__reviews-label {\n  white-space: nowrap;\n}\n\n\/* .hm-hero__alt \u2014 REMOVED 2026-09-14. This rule styled the hero's secondary link\n   until 2026-09-13, when that link became `btn btn--ghost` (the change recorded ~30\n   lines below as \"replacing `btn--block` + `.hm-hero__alt`\"). The replacement landed;\n   the rule did not leave. It then sat here styled, registered in SYSTEM_ADDITIONS as a\n   deliberate addition to HOME's vocabulary, and matching zero elements -- and the\n   comment further down documents a real bug caused by reasoning about its leftover\n   `color: var(--ivory)` as if it were still live.\n\n   Found by tests\/test_additions_render.py, which asserts that every class this system\n   adds to HOME actually reaches an element. Dead CSS that the documentation presents\n   as a feature is the same defect as a rule nothing applies, and it is how the next\n   person concludes the hero has a treatment it has not had since September 13. *\/\n\/* .hm-hero__actions \u2014 HOME's paired-CTA row, transcribed verbatim from\n   reference\/home.css. Added 2026-09-13, replacing `btn--block` + `.hm-hero__alt`\n   in the hero.\n\n   Why: the hero shipped one full-width `btn--block` button followed by a bare\n   text link. Measured on the live page, that button rendered 359px wide in a\n   390px viewport (the owner's \"the button is full width?\"), and the secondary\n   path \u2014 640 impressions of measured demand against the primary's 32 \u2014 was a\n   wrapping underlined link, not a control. `btn--block` is a SYSTEM_ADDITIONS\n   class HOME does not ship; HOME pairs its hero CTAs in this flex row instead.\n\n   At <=600px HOME switches to nowrap with flex:1 1 0, so the two buttons split\n   the row 50\/50 rather than stacking \u2014 which is what makes a paired CTA work at\n   390px at all. *\/\n.et-l--post .hm-hero__actions {\n  display: flex;\n  gap: 12px;\n  flex-wrap: wrap;\n  \/* Owner 2026-10-01 (\"review to buttons\" not tight enough): --s-4, desktop --s-5, down from HOME's 28px.\n     Ink gap from the reviews line to the buttons at 390: 32px -> 18px. *\/\n  margin-top: var(--s-4);\n}\n@media (min-width: 760px) {\n  .et-l--post .hm-hero__actions {\n    margin-top: var(--s-5);\n  }\n}\n\n\/* Wrap translated labels between words, never inside the action verb. *\/\n.et-l--post .hm-hero__actions .btn {\n  white-space: normal;\n  line-height: 1.35;\n  text-align: center;\n  overflow-wrap: normal;\n  justify-content: center;\n}\n\n\/* GROUND-AWARE GHOST BUTTON. Added 2026-09-14.\n\n   `--btn-ghost-fg` is a single global value (var(--ink)) declared once at the system\n   root, with no on-dark variant -- so the hero's secondary call to action rendered\n   near-black type on a dark photograph. Measured on composited pixels, worst decile\n   inside the label's own box: 1.62:1 at 390 and 2.01:1 at 1440 against a 4.5 floor\n   (12px\/600 is not \"large text\"). An SC 1.4.3 failure on every page carrying a hero\n   -- and it is the path PRODUCT.md's second design principle depends on, since \"let\n   the space sell\" is served by \"Take the tour\", which was the unreadable one.\n\n   Cause: on 2026-09-13 `.hm-hero__alt` (which carried `color: var(--ivory)`) was\n   replaced by `.hm-hero__actions`; the replacement inherited the flex layout and not\n   the recolour. The comment above `.hm-hero__alt` still described the ivory treatment\n   as live. A comment outlived its implementation -- which is why this is a TOKEN\n   variant rather than a one-off colour: the next component over a photograph needs\n   the same pair, and until now the system had nowhere to put it.\n\n   The HOVER override is not optional. `.btn--ghost:hover` sets\n   `background: var(--btn-ghost-fg); color: var(--page-bg)`, so with the fg token\n   flipped to ivory that is ivory on ivory: fixing the rest state alone would have\n   traded an unreadable button for an invisible one. *\/\n.et-l--post .hm-hero__actions .btn--ghost {\n  --btn-ghost-fg: var(--ivory);\n  --btn-ghost-line: rgba(249, 240, 224, 0.55);\n}\n\n.et-l--post .hm-hero__actions .btn--ghost:hover {\n  color: var(--ink);\n}\n\n\/* Owner 2026-09-28 (rental LP): two EQUAL routes (both btn--invert) sit in HOME's one row on\n   phones (\"the stacked buttons on mobile do not look good\"). Short labels fit one line each once\n   the arrows drop and the tracking tightens to .14em; HOME's ghost pair never matches this. *\/\n@media (max-width: 600px) {\n  .et-l--post .hm-hero__actions:has(> .btn--invert + .btn--invert) .btn { letter-spacing: 0.14em; }\n  .et-l--post .hm-hero__actions:has(> .btn--invert + .btn--invert) .arrow { display: none; }\n}\n@media (max-width: 600px) {\n  .et-l--post .hm-hero__actions {\n    flex-wrap: nowrap;\n    gap: 10px;\n  }\n  .et-l--post .hm-hero__actions .btn {\n    flex: 1 1 0;\n    min-width: 0;\n    justify-content: center;\n    padding-left: 14px;\n    padding-right: 14px;\n  }\n}\n\n@media (max-width: 359px) {\n  .et-l--post .hm-hero__actions .btn {\n    padding-left: 10px;\n    padding-right: 10px;\n    letter-spacing: 0.12em;\n  }\n}\n\/* Round 9 (owner: \"do your recommendation\" -- RENT STUDIO solid with its arrow, BOOK A SHOOT ghost):\n   at HOME's .22em the arrow wrapped to a second line at 360 and 375. Opt-in via actions_style \"compact\".\n   2026-10-01 (A24): the pair keeps HOME's .22em down to 375 by giving back side padding instead\n   (10px, the same step HOME's hero takes below 360); measured one line, 58px, at 375 and 390.\n   360-374 still needs .14em: at .22em \"RENT STUDIO \u2192\" wraps there even at 10px. Below 360 the\n   general step above (.12em, 10px) applies. Placed after the general phone rules, which it overrides. *\/\n@media (max-width: 600px) {\n  .et-l--post .hm-hero__actions--compact .btn { padding-left: 10px; padding-right: 10px; }\n}\n@media (min-width: 360px) and (max-width: 374px) {\n  .et-l--post .hm-hero__actions--compact .btn { letter-spacing: 0.14em; }\n}\n\n\/* HOME's responsive background video and original subhead grouping. *\/\n.et-l--post .hm-bgvid {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  object-position: center;\n  pointer-events: none;\n}\n.et-l--post .hm-hero__meta:empty {\n  display: none;\n}\n.et-l--post .hm-hero__actions .btn--invert {\n  background: var(--ivory);\n  color: var(--ink);\n}\n.et-l--post .hm-hero__actions .btn--invert:hover {\n  background: #8D8175;\n  color: #000;\n}\n\/* Reduced motion: the hero's script pauses the video, so the visitor keeps its still frame. Hiding\n   it would leave an empty hero now that a video hero has no poster (owner 2026-10-02). *\/\n\n\/* With an adjacent trust strip, the strip closes the first fold. *\/\n.et-l--post .hm-hero[style*=\"--cc-hero-fold\"] {\n  min-height: var(--cc-hero-fold);\n}\n\n\/* Phase 2: the approved HOME display\/lead\/actions on a content-sized plain ground.\n   No artificial media space, compulsory eyebrow, metadata row or viewport height. *\/\n.et-l--post .cc-hero-plain {\n  padding-block: clamp(48px, 7vw, 96px) var(--s-6);\n}\n.et-l--post .cc-hero-plain__title {\n  max-width: 100%;\n  margin: 0;\n  font-family: var(--font-display);\n  font-size: var(--t-hero-size);\n  line-height: var(--t-hero-lh);\n  letter-spacing: var(--t-hero-ls);\n  font-weight: 600;\n  text-wrap: balance;\n  overflow-wrap: break-word;\n}\n.et-l--post .cc-hero-plain__sub {\n  max-width: 60ch;\n  margin: var(--s-5) 0 0;\n  font-family: var(--font-body);\n  font-size: var(--t-lead-size);\n  line-height: 1.55;\n  font-weight: 500;\n  color: var(--ink);\n  text-wrap: pretty;\n}\n.et-l--post .cc-hero-plain__actions {\n  display: flex;\n  flex-wrap: wrap;\n  gap: var(--s-3);\n  margin-top: var(--s-5);\n}\n.et-l--post .cc-hero-plain__sub:empty,\n.et-l--post .cc-hero-plain__actions:empty { display: none; }\n\/* The explicit light header is fixed. Reserve its measured 71px height before\n   the normal section rhythm; isolated specimens need no header reservation. *\/\nbody:has(#main-header[data-cc-nav-context=\"light\"]) .et-l--post .cc-hero-plain {\n  padding-top: calc(var(--cc-header-height) + clamp(48px, 7vw, 96px)) !important;\n}\n@media (max-width: 760px) {\n  body:has(#main-header[data-cc-nav-context=\"light\"]) .et-l--post .cc-hero-plain {\n    padding-top: calc(var(--cc-header-height) + var(--s-6)) !important;\n  }\n}\n@media (max-width: 600px) {\n  .et-l--post .cc-hero-plain__actions .btn { flex: 1 1 auto; justify-content: center; }\n}\n\/* Retain the opening's identity and supporting value facts. *\/\n.et-l--post .cc-hero-plain__label { margin: 0 0 var(--s-4); font-size: var(--t-meta-size); font-weight: 600; color: var(--graphite); }\n.et-l--post .cc-hero-plain__label:empty { display: none; }\n.et-l--post .cc-hero-plain__facts { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6); padding: 0; margin: var(--s-6) 0 0; list-style: none; }\n.et-l--post .cc-hero-plain__facts li { display: flex; gap: var(--s-2); font: 600 var(--t-meta-size)\/1.6 var(--font-body); color: var(--ink); }\n.et-l--post .cc-hero-plain__facts li::before { content: '\u2726'; }\n.et-l--post .cc-hero-plain__facts:empty { display: none; }\n@media (max-width: 760px) {\n  .et-l--post .cc-hero-plain__facts { flex-direction: column; gap: var(--s-2); margin-top: var(--s-5); }\n}\n\n\/* Phase 2 studio introductions share CC typography, grounds, controls and facts.\n   Editorial is the common layer; the two other pairs add composition only. *\/\n.et-l--post .cc-intro { padding: clamp(32px,4.5vw,64px) 0; color: var(--ink); }\n.et-l--post .cc-intro-grid { display: grid; gap: 28px; }\n.et-l--post .cc-intro h2 { font: 600 clamp(32px,3.65vw,52px)\/1.04 var(--font-display); letter-spacing: -.015em !important; color: var(--ink) !important; margin: 0; padding: 0; text-wrap: balance; }\n.et-l--post .cc-intro h3 { margin: 0; font: 600 25px\/1.1 var(--font-display); }\n.et-l--post .cc-intro p { margin: 0; font: 500 15px\/1.6 var(--font-body); }\n.et-l--post .cc-intro-heading > p { margin-top: 20px; max-width: 54ch; }\n.et-l--post .cc-intro-facts { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); margin: 0; padding: 20px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); gap: 12px; }\n.et-l--post .cc-intro-facts dt { font: 600 clamp(24px,2.5vw,34px)\/1.1 var(--font-display); }\n.et-l--post .cc-intro-facts dd { font: 500 11px\/1.45 var(--font-body); margin: 8px 0 0; }\n.et-l--post .cc-intro .cc-intro-included h3 { font: 600 14px\/1.4 var(--font-body); margin-bottom: 8px; }\n.et-l--post .cc-intro-included small { display: block; margin-top: 10px; font: 500 12px\/1.5 var(--font-body); color: var(--graphite); }\n.et-l--post .cc-intro-routes { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); column-gap: 24px; row-gap: 0; }\n.et-l--post .cc-intro-route { min-width: 0; display: grid; grid-row: span 5; grid-template-rows: subgrid; align-items: start; }\n.et-l--post .cc-intro .cc-intro-route__desc { font-size: 13px; margin-top: 10px; }\n.et-l--post .cc-intro .cc-intro-route__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin-top: 20px; }\n.et-l--post .cc-intro-route__price strong { font: 600 38px\/1.05 var(--font-display); }\n.et-l--post .cc-intro-route__price span { font: 500 12px\/1.4 var(--font-body); }\n.et-l--post .cc-intro .cc-intro-route__qualifier { font-size: 12px; margin: 8px 0 18px; }\n.et-l--post .cc-intro-route .btn { margin-top: 0; align-self: stretch; min-height: 48px; padding: 14px 18px; font-size: 11px; letter-spacing: .1em; width: 100%; text-align: center; justify-content: center; white-space: normal; }\n.et-l--post .cc-intro-details { border-top: 1px solid var(--line); min-width: 0; }\n.et-l--post .cc-intro-detail { border-bottom: 1px solid var(--line); }\n.et-l--post .cc-intro-detail summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 22px 0; cursor: pointer; }\n.et-l--post .cc-intro-detail summary::-webkit-details-marker { display: none; }\n.et-l--post .cc-intro-detail summary strong { display: block; font: 600 25px\/1.15 var(--font-display); }\n.et-l--post .cc-intro-detail summary small { display: block; font: 500 12px\/1.45 var(--font-body); margin-top: 5px; color: var(--graphite); }\n.et-l--post .cc-intro-detail summary i { flex: 0 0 16px; height: 16px; position: relative; }\n.et-l--post .cc-intro-detail summary i::before, .et-l--post .cc-intro-detail summary i::after { content: ''; position: absolute; background: currentColor; top: 7px; width: 16px; height: 1px; }\n.et-l--post .cc-intro-detail summary i::after { transform: rotate(90deg); transition: transform .2s ease; }\n.et-l--post .cc-intro-detail[open] summary i::after { transform: rotate(0); }\n.et-l--post .cc-intro-detail__body { padding: 0 0 24px; font: 500 14px\/1.6 var(--font-body); }\n.et-l--post .cc-intro-detail__body p { font-size: 14px; margin-bottom: 16px; }\n.et-l--post .cc-intro-detail__body h3 { margin: 18px 0 10px; font: 600 14px\/1.4 var(--font-body); }\n.et-l--post .cc-intro-detail__body ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; }\n.et-l--post .cc-intro-table { max-width: 100%; margin-top: 24px; }\n.et-l--post .cc-intro-table table { width: 100%; border-collapse: collapse; font: 500 12px\/1.5 var(--font-body); }\n.et-l--post .cc-intro-table caption { text-align: left; font-weight: 600; font-size: 14px; margin-bottom: 10px; }\n.et-l--post .cc-intro-table th, .et-l--post .cc-intro-table td { text-align: left; padding: 10px 8px 10px 0; border-bottom: 1px solid var(--line); vertical-align: top; }\n.et-l--post .cc-intro-table thead th { font-weight: 600; }\n.et-l--post .cc-intro-table tbody th { font-weight: 500; }\n@media (max-width: 600px) {\n  .et-l--post .cc-intro { padding: 32px 0 !important; }\n  .et-l--post .cc-intro-grid { gap: 24px; }\n  .et-l--post .cc-intro h2 { font-size: var(--t-hero-size); }\n  .et-l--post .cc-intro-facts { gap: 8px; }\n  .et-l--post .cc-intro-facts dd { font-size: 10px; }\n  .et-l--post .cc-intro-routes { column-gap: 16px; row-gap: 0; }\n  .et-l--post .cc-intro-route h3 { font-size: var(--t-h3-size); }\n  .et-l--post .cc-intro-route .btn { padding: 13px 8px; font-size: 10px; }\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .cc-intro * { transition: none !important; scroll-behavior: auto !important; }\n}\n\n\/* A: one mobile reading column; each service owns its price, details and action. *\/\n.et-l--post .cc-intro--editorial .cc-intro-grid { display: grid; grid-template-columns: minmax(0,1fr); gap: 32px; }\n.et-l--post .cc-intro--editorial .cc-intro-heading p { margin-top: 18px; max-width: 46ch; font-size: 16px; line-height: 1.65; }\n.et-l--post .cc-intro--editorial .cc-intro-detail summary { display: grid; grid-template-columns: minmax(0,1fr) 16px; gap: 6px 12px; min-height: 88px; padding: 18px 0; }\n.et-l--post .cc-intro--editorial .cc-intro-detail summary strong { font: 600 16px\/1.4 var(--font-body); }\n.et-l--post .cc-intro--editorial .cc-intro-detail summary small { grid-column: 1; font: 500 12px\/1.45 var(--font-body); margin: 0; }\n.et-l--post .cc-intro--editorial .cc-intro-detail summary i { grid-column: 2; grid-row: 1; }\n.et-l--post .cc-intro--editorial .cc-intro-route__price { margin: 0; display: block; white-space: nowrap; font: 600 14px\/1.4 var(--font-body); }\n.et-l--post .cc-intro--editorial .cc-intro-table { margin-top: 28px; }\n@media (min-width: 1000px) {\n  .et-l--post .cc-intro--editorial .cc-intro-grid { grid-template-columns: .9fr 1.1fr; gap: var(--s-8); align-items: start; }\n  .et-l--post .cc-intro--editorial .cc-intro-detail summary { grid-template-columns: max-content minmax(0,1fr) 16px; gap: 8px 16px; min-height: 72px; padding: 20px 0; }\n  .et-l--post .cc-intro--editorial .cc-intro-detail summary small { grid-column: 2; align-self: center; white-space: nowrap; }\n  .et-l--post .cc-intro--editorial .cc-intro-detail summary i { grid-column: 3; }\n}\n\n\/* Space-first A: the studio sells the visit; pricing is a quieter guide. *\/\n\/* Owner 2026-09-22: the studio guide read as a stack of bold labels. It is a\n   specification list, so each feature gets a 22px line icon in its own column, the\n   title keeps the body role beside it on one baseline, and the description hangs\n   under the title on that same axis. The glyph set is closed and lives in\n   intro_content.py; a manifest names an icon, it never carries markup. *\/\n.et-l--post .cc-intro--editorial .cc-intro-specs { margin: 0; display: grid; gap: 22px; }\n.et-l--post .cc-intro--editorial .cc-intro-specs dt { display: grid; grid-template-columns: 22px minmax(0,1fr); column-gap: 12px; align-items: center; margin: 0 0 6px; font: 600 16px\/1.375 var(--font-body); }\n.et-l--post .cc-intro--editorial .cc-intro-specs dd { margin: 0 0 0 34px; font: 500 14px\/1.65 var(--font-body); color: var(--graphite); }\n.et-l--post .cc-intro-specs__icon { display: block; width: 22px; height: 22px; color: var(--ink); }\n.et-l--post .cc-intro-specs__icon svg { display: block; width: 100%; height: 100%; }\n.et-l--post .cc-intro--editorial .cc-intro-pricing .cc-intro-tabpanel { padding-top: 0; }\n\/* Owner 2026-09-22: HOME's two-cell price tab bar sits directly under the guide row. *\/\n.et-l--post .cc-intro--editorial .cc-intro-pricing .price-tabs { margin: 0 0 20px; }\n\n\/* C2 2026-09-22 -- .cc-rates: the compact studio-rental ledger. Eight durations in\n   three aligned columns on 46px rows, so the whole sheet reads in one phone screen;\n   the full-size .shoot-row ledger spent ~1,100px on the same eight numbers. Column\n   heads use the micro role, durations the body role, figures tabular so the two\n   price columns line up. The one featured row is ruled in ink instead of boxed, so\n   the ledger stays a ledger. *\/\n.et-l--post .cc-rates { margin: 0; }\n.et-l--post .cc-rates table { width: 100%; border-collapse: collapse; table-layout: auto; background: transparent; color: var(--ink); font-family: var(--font-body); }\n.et-l--post .cc-rates th, .et-l--post .cc-rates td { padding: 13px 0 13px 12px; border: 0; border-bottom: 1px solid var(--line); text-align: right; vertical-align: middle; white-space: nowrap; font-variant-numeric: tabular-nums; }\n.et-l--post .cc-rates thead th { padding: 0 0 10px 12px; border-bottom: 1px solid var(--ink); font-size: var(--t-micro-size); font-weight: 600; letter-spacing: var(--t-micro-ls); line-height: var(--t-micro-lh); text-transform: uppercase; color: var(--graphite); white-space: normal; vertical-align: bottom; }\n.et-l--post .cc-rates th:first-child, .et-l--post .cc-rates td:first-child { padding-left: 0; text-align: left; }\n\/* Owner 2026-09-22: the duration and its flag stay on ONE line at every width. The two\n   price columns size to their content (width:1% under auto layout) so the first column\n   keeps the room; at very narrow phones the flag and column heads tighten instead of\n   wrapping. *\/\n.et-l--post .cc-rates th:nth-child(2), .et-l--post .cc-rates th:nth-child(3) { width: 1%; }\n.et-l--post .cc-rates tbody th { font-size: 14px; font-weight: 600; line-height: 1.3; }\n.et-l--post .cc-rates tbody td { font-size: 15px; font-weight: 500; line-height: 1.3; letter-spacing: -0.01em; }\n.et-l--post .cc-rates tbody td:nth-child(2) { font-weight: 600; }\n\/* v7 review: price.css sets the flag at opacity .72 -- #555 became #83807C, 3.46:1 at 11px. Opaque it is ~6.6:1. *\/\n.et-l--post .cc-rates .shoot-row__flag { vertical-align: 0.12em; margin-left: 8px; letter-spacing: 0.1em; white-space: nowrap; opacity: 1; }\n\/* Owner 2026-09-27: a linked price opens its exact booking choice. The link fills the row height\n   so the tap target is the full 46px row, not the figure's glyphs. *\/\n.et-l--post .cc-rates td a { display: inline-block; min-width: 44px; text-align: right; margin: -13px 0; padding: 13px 0; color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }\n.et-l--post .cc-rates td a:hover { color: #8D8175; }\n.et-l--post .cc-rates td a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }\n\/* Owner 2026-09-22: a package row keeps HOME's two-column shape at EVERY width --\n   name and price on ONE line, meta beneath the name. hierarchy.css stacks .shoot-row\n   below 600px for pages whose price string also carries the duration (\"$750 \u00b7 2\n   hours\"); here the duration lives in .shoot-row__meta, so the row has the room. *\/\n.et-l--post .cc-intro-pricing .shoot-row { grid-template-columns: minmax(0,1fr) auto; align-items: start; }\n.et-l--post .cc-intro-pricing .shoot-row__name { min-width: 0; }\n.et-l--post .cc-intro-pricing .shoot-row__name .shoot-row__flag { white-space: nowrap; opacity: 1; }\n\/* The price sits ON the package name's line, not centred over the whole row: the\n   same alignment the rate ledger beside it uses, and the thing the owner asked for. *\/\n.et-l--post .cc-intro-pricing .shoot-row__right { grid-column: 2; grid-row: 1; align-self: center; margin-top: 0; width: auto; justify-content: flex-end; }\n.et-l--post .cc-intro-pricing .shoot-row__price { white-space: nowrap; }\n\/* Owner 2026-09-22: \"shrink most pop\" -- the marker stays BESIDE the package name at\n   phone widths, so name, marker and price share one line. All three step down\n   together (roles first, existing literals for the marker) because shrinking the\n   marker alone cannot buy the ~90px the row needs. *\/\n@media (max-width: 759px) {\n  .et-l--post .cc-intro-pricing .shoot-row__name { font-size: var(--t-body-size); }\n  .et-l--post .cc-intro-pricing .shoot-row__price { font-size: var(--t-h3-size); }\n  .et-l--post .cc-intro-pricing .shoot-row__name .shoot-row__flag { font-size: 10px; letter-spacing: 0.06em; margin-left: 8px; }\n}\n\/* 375px is a real phone (SE, 8, 13 mini) and the marker landed one word short there.\n   The row gives back its own horizontal padding and column gap rather than shrinking\n   the name a second time. *\/\n@media (max-width: 430px) {\n  .et-l--post .cc-intro-pricing .shoot-row { padding-left: 14px; padding-right: 14px; column-gap: 12px; }\n  .et-l--post .cc-intro-pricing .shoot-row__name .shoot-row__flag { letter-spacing: 0.04em; margin-left: 6px; }\n}\n@media (max-width: 360px) {\n  .et-l--post .cc-rates th, .et-l--post .cc-rates td { padding-left: 8px; }\n  .et-l--post .cc-rates thead th { font-size: 10px; letter-spacing: 0.06em; }\n  .et-l--post .cc-rates tbody th { font-size: 13px; }\n  .et-l--post .cc-rates tbody td { font-size: 14px; }\n  .et-l--post .cc-rates .shoot-row__flag { font-size: 10px; letter-spacing: 0.05em; margin-left: 6px; }\n}\n\/* Two further steps, set by where the marker actually stopped fitting rather than by\n   round numbers: 374 is the last width the 16px name survives, 339 the last for 15px.\n   Measured per width in tests\/test_studio_introduction.py. *\/\n@media (max-width: 374px) {\n  .et-l--post .cc-intro-pricing .shoot-row__name { font-size: 15px; }\n  .et-l--post .cc-intro-pricing .shoot-row__price { font-size: 18px; }\n  .et-l--post .cc-intro-pricing .shoot-row__name .shoot-row__flag { letter-spacing: 0.02em; }\n  .et-l--post .cc-intro-pricing .shoot-row__right { gap: 8px; }\n}\n\/* Below 360 the decorative arrow goes. It carries no meaning -- the whole row is the\n   link -- and it and its gap were the last ~30px standing between the marker and the\n   name's line. *\/\n@media (max-width: 359px) {\n  .et-l--post .cc-intro-pricing .shoot-row { padding-left: 12px; padding-right: 12px; column-gap: 10px; }\n  .et-l--post .cc-intro-pricing .shoot-row__name { font-size: 14px; }\n  .et-l--post .cc-intro-pricing .shoot-row__price { font-size: var(--t-lead-size); }\n  .et-l--post .cc-intro-pricing .shoot-row__name .shoot-row__flag { letter-spacing: 0; margin-left: 5px; }\n  .et-l--post .cc-intro-pricing .shoot-row__arrow { display: none; }\n}\n.et-l--post .cc-rates .cc-rates__feat th, .et-l--post .cc-rates .cc-rates__feat td,\n.et-l--post .cc-rates tr:has(+ .cc-rates__feat) th, .et-l--post .cc-rates tr:has(+ .cc-rates__feat) td { border-bottom-color: var(--ink); }\n.et-l--post .cc-rates + .rent-foot { margin-top: 24px; }\n@media (min-width: 760px) {\n  .et-l--post .cc-rates th:nth-child(2), .et-l--post .cc-rates th:nth-child(3) { width: 160px; min-width: 160px; }\n  .et-l--post .cc-rates th, .et-l--post .cc-rates td { padding-top: 15px; padding-bottom: 15px; }\n  .et-l--post .cc-rates tbody th { font-size: 15px; }\n  .et-l--post .cc-rates tbody td { font-size: 16px; }\n}\n@media (min-width: 1100px) {\n  .et-l--post .cc-intro--editorial .cc-intro-specs { grid-template-columns: repeat(2,minmax(0,1fr)); column-gap: 32px; row-gap: 28px; }\n}\n\n\/* Phase 2: three owner-requested compositions of the same studio introduction.\n   The image proves the space before the detailed guide; control type is uniform. *\/\n.et-l--post .cc-intro--editorial .cc-intro-grid { grid-template-areas: 'heading' 'photo' 'details'; gap: 28px; }\n.et-l--post .cc-intro--editorial .cc-intro-heading { grid-area: heading; }\n.et-l--post .cc-intro--editorial .cc-intro-photo { grid-area: photo; margin: 0; min-height: 0; height: auto; aspect-ratio: 3 \/ 2; overflow: hidden; }\n.et-l--post .cc-intro--editorial .cc-intro-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 55%; }\n.et-l--post .cc-intro--editorial .cc-intro-details { grid-area: details; }\n\/* 2026-10-01 (A20): the wide frame is the photo's own shape (the template's width\/height, 1850x960) at\n   every width. 16:9 cut 8% of its width on phones; 5:2 cut 23% of its height on desktop, the top of\n   the arch. Nothing is cropped now. *\/\n.et-l--post .cc-intro--editorial[data-intro-layout=\"wide\"] .cc-intro-photo { aspect-ratio: 1850 \/ 960; }\n.et-l--post .cc-intro--editorial[data-intro-layout=\"photo-first\"] .cc-intro-grid { grid-template-areas: 'photo' 'heading' 'details'; }\n.et-l--post .cc-intro--editorial[data-intro-layout=\"photo-first\"] .cc-intro-photo { aspect-ratio: 16 \/ 9; }\n@media (min-width: 1000px) {\n  .et-l--post .cc-intro--editorial .cc-intro-grid { column-gap: 64px; row-gap: 32px; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"beside\"] .cc-intro-grid { grid-template-columns: .95fr 1.05fr; grid-template-areas: 'heading details' 'photo details'; grid-template-rows: auto 1fr; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"beside\"] .cc-intro-photo { align-self: start; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"wide\"] .cc-intro-grid { grid-template-columns: 1fr; grid-template-areas: 'heading' 'photo' 'details'; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"wide\"] .cc-intro-heading { display: block; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"wide\"] .cc-intro-heading h2 { max-width: 26ch; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"wide\"] .cc-intro-heading p { margin-top: 20px; max-width: 76ch; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"photo-first\"] .cc-intro-grid { grid-template-columns: 1.1fr .9fr; grid-template-areas: 'photo heading' 'details details'; align-items: center; gap: 40px 64px; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"photo-first\"] .cc-intro-photo { aspect-ratio: 4 \/ 3; }\n  .et-l--post .cc-intro--editorial:not([data-intro-layout=\"beside\"]) .cc-intro-specs { grid-template-columns: repeat(3,minmax(0,1fr)); gap: 28px 40px; }\n}\n\n\/* Owner 2026-09-25: \/tour\/ reuses HOME's introduction without its photo, because the set cards\n   above it already show the space. `text` is `wide` minus the figure: the figure leaves the layout\n   and the accessibility tree, and its lazy image is never requested. *\/\n.et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-grid { grid-template-areas: 'heading' 'details'; }\n.et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-photo { display: none; }\n\/* Owner 2026-09-25: \/tour\/ drops the introduction paragraph. An empty lead leaves no box behind,\n   so the grid gap alone separates the heading from the guide. *\/\n.et-l--post .cc-intro--editorial .cc-intro-heading > p:empty { display: none; }\n@media (min-width: 1000px) {\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-grid { grid-template-columns: 1fr; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-heading { display: block; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-heading h2 { max-width: 26ch; }\n  .et-l--post .cc-intro--editorial[data-intro-layout=\"text\"] .cc-intro-heading p { margin-top: 20px; max-width: 76ch; }\n}\n\n\/* Phase 2: two distinct service paths above shared studio details. *\/\n.et-l--post .cc-intro--services .cc-intro-heading { display: grid; grid-template-columns: 1.15fr 1fr; gap: 64px; align-items: end; }\n.et-l--post .cc-intro--services .cc-intro-heading p { margin: 0; }\n.et-l--post .cc-intro--services .cc-intro-facts { border: 0; padding: 0; grid-template-columns: repeat(4,1fr); }\n.et-l--post .cc-intro--services .cc-intro-facts > div { display: flex; align-items: baseline; gap: 10px; }\n.et-l--post .cc-intro--services .cc-intro-facts dd { margin: 0; }\n.et-l--post .cc-intro--services .cc-intro-routes { gap: 0; border: 1px solid var(--ink); }\n.et-l--post .cc-intro--services .cc-intro-route { padding: 32px; background: var(--warm-white); }\n.et-l--post .cc-intro--services .cc-intro-route + .cc-intro-route { border-left: 1px solid var(--line); background: transparent; }\n.et-l--post .cc-intro--services .cc-intro-route h3 { font-size: var(--t-h2-size); }\n.et-l--post .cc-intro--services .cc-intro-route__price strong { font-size: var(--t-display-size); }\n.et-l--post .cc-intro--services .cc-intro-route .btn { max-width: 280px; }\n.et-l--post .cc-intro--services .cc-intro-included { display: grid; grid-template-columns: 200px 1fr; column-gap: 30px; padding: 0 0 4px; }\n.et-l--post .cc-intro--services .cc-intro-included small { grid-column: 2; }\n.et-l--post .cc-intro--services .cc-intro-details { display: grid; grid-template-columns: 1fr 1fr; column-gap: 48px; align-items: start; }\n@media (max-width: 800px) {\n  .et-l--post .cc-intro--services .cc-intro-heading { display: block; }\n  .et-l--post .cc-intro--services .cc-intro-heading p { margin-top: 18px; }\n  .et-l--post .cc-intro--services .cc-intro-facts > div { display: block; }\n  .et-l--post .cc-intro--services .cc-intro-facts dd { margin-top: 8px; }\n  .et-l--post .cc-intro--services .cc-intro-included, .et-l--post .cc-intro--services .cc-intro-details { display: block; }\n}\n@media (max-width: 600px) {\n  .et-l--post .cc-intro--services .cc-intro-route { padding: 20px 14px; }\n  .et-l--post .cc-intro--services .cc-intro-route h3 { font-size: var(--t-h3-size); }\n  .et-l--post .cc-intro--services .cc-intro-route__price strong { font-size: var(--t-display-size); }\n\n}\n\n\/* Phase 2: existing studio imagery with a concise, navigable studio guide. *\/\n.et-l--post .cc-intro--visual .cc-intro-grid { grid-template-columns: .9fr 1.1fr; grid-template-areas: 'photo heading' 'photo facts' 'photo included' 'routes routes' 'details details'; column-gap: var(--s-7); }\n.et-l--post .cc-intro--visual .cc-intro-heading { grid-area: heading; }\n.et-l--post .cc-intro--visual .cc-intro-facts { grid-area: facts; }\n.et-l--post .cc-intro--visual .cc-intro-included { grid-area: included; }\n.et-l--post .cc-intro--visual .cc-intro-routes { grid-area: routes; border-top: 1px solid var(--line); padding-top: 28px; }\n.et-l--post .cc-intro--visual .cc-intro-details { grid-area: details; }\n.et-l--post .cc-intro-photo { grid-area: photo; margin: 0; min-height: 400px; }\n.et-l--post .cc-intro-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }\n.et-l--post .cc-intro--visual .cc-intro-route { grid-row: auto; grid-template-rows: auto; display: grid; grid-template-columns: 1fr auto; column-gap: 24px; }\n.et-l--post .cc-intro--visual .cc-intro-route h3, .et-l--post .cc-intro--visual .cc-intro-route__desc { grid-column: 1; }\n.et-l--post .cc-intro--visual .cc-intro-route__price { grid-column: 2; grid-row: 1 \/ span 2; margin: 0; display: block; text-align: right; }\n.et-l--post .cc-intro--visual .cc-intro-route__price span { display: block; margin-top: 8px; }\n.et-l--post .cc-intro--visual .cc-intro-route__qualifier { grid-column: 1 \/ -1; }\n.et-l--post .cc-intro--visual .cc-intro-route .btn { grid-column: 1 \/ -1; }\n.et-l--post .cc-intro-tabs { display: flex; border-bottom: 1px solid var(--ink); gap: 0; }\n.et-l--post .cc-intro-tabs button { flex: 1; padding: 18px 12px; min-height: 56px; border: 0; border-bottom: 3px solid transparent; background: none; font: 600 13px\/1.4 var(--font-body); color: var(--ink); cursor: pointer; }\n.et-l--post .cc-intro-tabs button[aria-selected=\"true\"] { border-bottom-color: var(--ink); background: var(--warm-white); }\n.et-l--post .cc-intro-tabpanel { padding: 24px 0 0; }\n.et-l--post .cc-intro-tabpanel[hidden] { display: none; }\n.et-l--post .cc-intro--visual .cc-intro-tabpanel .cc-intro-detail__body { columns: 2; column-gap: var(--s-7); }\n.et-l--post .cc-intro-tabpanel h3, .et-l--post .cc-intro-tabpanel table, .et-l--post .cc-intro-tabpanel li { break-inside: avoid; }\n@media (max-width: 800px) {\n  .et-l--post .cc-intro--visual .cc-intro-grid { grid-template-columns: 1fr; grid-template-areas: 'heading' 'facts' 'included' 'routes' 'photo' 'details'; }\n  .et-l--post .cc-intro-photo { min-height: 0; height: 230px; }\n  .et-l--post .cc-intro--visual .cc-intro-route { display: grid; grid-template-columns: 1fr; grid-row: span 5; grid-template-rows: subgrid; }\n  .et-l--post .cc-intro--visual .cc-intro-route__price { grid-column: 1; grid-row: auto; margin-top: 18px; text-align: left; }\n  .et-l--post .cc-intro-tabs { display: grid; grid-template-columns: 1fr 1fr; }\n  .et-l--post .cc-intro--visual .cc-intro-tabpanel .cc-intro-detail__body { columns: auto; }\n}\n\n\n\/* location.css \u2014 HOME's map block (.hm-map), extracted verbatim from\n   reference\/home.css (offset ~108645-109007, one contiguous block, already\n   .et-l--post-scoped in the source). One declaration found for each\n   selector below \u2014 no cascade conflicts, no duplicate elsewhere in the\n   file. HOME's own live page (scratchpad\/home.html, offset ~149625) only\n   fills the .hm-map__frame iframe and leaves .hm-map__title\/.hm-map__addr\n   unused, but the CSS rules for both already exist and ship the address\n   text this component is built to carry \u2014 the only component allowed to,\n   per F10.\n\n   bk-section \/ container-bk \/ bk-h2 \/ reveal are base.css primitives,\n   referenced here, not duplicated. *\/\n.et-l--post .hm-map {\n  width: 100%;\n  margin: 0;\n  padding: 0;\n}\n.et-l--post .hm-map__title {\n  margin: 0 0 6px;\n}\n.et-l--post .hm-map__addr {\n  font-family: var(--font-body);\n  color: var(--graphite);\n  font-size: 14px;\n  margin: 0 0 22px;\n}\n.et-l--post .hm-map__frame {\n  width: 100%;\n  height: clamp(380px, 50vw, 560px);\n  border: 0;\n  display: block;\n}\n\n\/* 2026-09-25: the address is an <h3>, and the live theme's bare h1-h6\/h3 rules\n   (0,0,1) render it as display Bodoni at 19px\/35px, weight 600, line-height 1em,\n   with 10px bottom padding. Measured on live \/podcast-studio-miami\/. The approved\n   specimen shows Montserrat 700 in ink. Scoped to this component because map.html's\n   <h2> shares .hm-map__title and must keep the display face. *\/\n.et-l--post [data-screen-label=\"location\"] .hm-map__title {\n  font-family: var(--font-body);\n  font-size: var(--t-lead-size);\n  font-weight: 700;\n  line-height: normal;\n  color: var(--ink);\n  padding-bottom: 0;\n}\n\n\/* map.css \u2014 HOME's location map band (.hm-map). Body extracted verbatim from\n   reference\/home.css by tools\/cc_system\/lift.py; every selector scoped to\n   .et-l--post. Re-run lift.py --classes hm-map hm-map__frame hm-map__title.\n\n   Why this component exists: 18 map sections across 18 pages (measured\n   2026-09-13, vocabulary.py) with no component \u2014 so the neighbourhood cohort\n   hand-rolled a map band ten times over.\n\n   No selector is declared twice; there is nothing to resolve.\n\n   The <iframe> element itself is supplied by the caller through map.html, not\n   by this stylesheet. .hm-map__frame fixes its height with a clamp, so the\n   iframe must NOT also carry width\/height attributes that fight it. *\/\n.et-l--post .hm-map {\n  width:100%;\n  margin:0;\n  padding:0;\n}\n.et-l--post .hm-map__title {\n  margin:0 0 6px;\n}\n.et-l--post .hm-map__frame {\n  width:100%;\n  height:clamp(380px, 50vw, 560px);\n  border:0;\n  display:block;\n}\n\n\/* HOME's map is a full-width band. Its edges are derived (`media` role, spacing.py):\n   flush against the feed above it and the footer below it. *\/\n.et-l--post [data-screen-label=\"map\"] .container-bk {\n  width: 100%;\n}\n.et-l--post [data-screen-label=\"map\"] .bk-h2:empty,\n.et-l--post [data-screen-label=\"map\"] .bk-lead:empty {\n  display: none;\n}\n.et-l--post [data-screen-label=\"map\"] .bk-h2:not(:empty),\n.et-l--post [data-screen-label=\"map\"] .bk-lead:not(:empty) {\n  width: min(1180px, 92vw);\n  margin-left: auto;\n  margin-right: auto;\n}\n\n\/* WHERE THE MAP MEETS THE FOOTER. Owner 2026-09-22, correcting a first attempt that\n   removed the footer's top padding: that was not what \"flush\" meant. Keep the padding.\n   What the owner can see is a grey hairline under the map, and measured at 1512 and\n   390 it is two separate 1px rows, not one:\n\n     map section bottom   7325.02\n     + 1px                the sticky anchor section, which renders 1px tall, in ivory\n     footer box top       7326.02, whose own `border-top: 1px solid var(--line)` is the\n                          grey line itself\n\n   The footer's CSS is inline in the Divi Theme Builder code module and is not\n   REST-writable, so this override lives in the page payload -- the documented second\n   exception to the `.et-l--post` scoping rule after `sticky`. Removing the border and\n   pulling the footer up by that one anchor pixel puts the footer's own ground directly\n   against the map's bottom edge, with nothing between them to see. It ships only in\n   the payload of a page carrying this band, which today is HOME alone. *\/\nbody:has(.et-l--post .hm-map) .bk-footer {\n  border-top: 0;\n  margin-top: -1px;\n}\n\n\/* marquee.css \u2014 HOME's services marquee (.hm-marquee), extracted verbatim\n   from reference\/home.css (offset ~83420). Every selector scoped to\n   .et-l--post per the project's CSS-specificity rule.\n\n   The `hmmarquee` keyframe this relies on lives in base.css, not here \u2014 see\n   the comment there for why. *\/\n.et-l--post .hm-marquee {\n  overflow: hidden;\n  border-bottom: 1px solid var(--line);\n  padding: 16px 0;\n  background: var(--warm-white);\n  cursor: pointer;\n}\n.et-l--post .hm-marquee__track {\n  display: flex;\n  width: max-content;\n  animation: hmmarquee 32s linear infinite;\n}\n.et-l--post .hm-marquee:hover .hm-marquee__track {\n  animation-play-state: paused;\n}\n.et-l--post .hm-marquee__item {\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: clamp(26px, 4.4vw, 48px);\n  letter-spacing: -0.01em;\n  padding: 0 0.45em;\n  display: inline-flex;\n  align-items: center;\n  gap: 0.5em;\n  white-space: nowrap;\n  color: var(--ink);\n  line-height: 1.2;\n}\n.et-l--post .hm-marquee__item::after {\n  content: \"\u25c6\";\n  font-size: 0.34em;\n  color: var(--accent);\n  font-family: var(--font-body);\n}\n\n@media (prefers-reduced-motion: reduce) {\n  \/* FIX 4 (Task 10): this was the one animated mechanism prefers-reduced-motion\n     never covered at all \u2014 press.css's .ccp-track had its own query, this one\n     didn't. Same treatment as .ccp-track: stop the animation and wrap the\n     (duplicated, for the seamless loop) track into a static row instead of\n     leaving it frozen mid-scroll, where only whatever fits the viewport at\n     that instant would ever be visible. *\/\n  .et-l--post .hm-marquee__track {\n    animation: none;\n    flex-wrap: wrap;\n    justify-content: center;\n    width: 100%;\n  }\n  .et-l--post .hm-marquee__item[aria-hidden=\"true\"] {\n    display: none;\n  }\n}\n\n\/* Phase 2 recovery: preserve portrait identity and the signed personal story. *\/\n.et-l--post .cc-media-prose__layout { display: grid; grid-template-columns: minmax(0, .76fr) minmax(0, 1.24fr); grid-template-areas: \"media heading\" \"media body\"; gap: var(--s-5) clamp(32px, 5vw, var(--s-8)); align-items: start; }\n.et-l--post .cc-media-prose__heading { grid-area: heading; margin: 0; line-height: 1.12; text-wrap: balance; }\n.et-l--post .cc-media-prose__figure { grid-area: media; min-width: 0; margin: 0; position: sticky; top: var(--s-5); }\n.et-l--post .cc-media-prose__portrait { position: relative; overflow: hidden; }\n.et-l--post .cc-media-prose__figure img { display: block; width: 100%; height: auto; aspect-ratio: 4 \/ 5; object-fit: cover; border-radius: 0; }\n.et-l--post .cc-media-prose__identity { position: absolute; inset: auto 0 0; padding: 48px 24px 24px; color: var(--ivory); background: linear-gradient(transparent, rgba(0,0,0,.8)); }\n.et-l--post .cc-media-prose__identity strong { display: block; font-family: var(--font-display); font-size: clamp(28px, 3vw, 34px); line-height: 1.1; font-weight: 600; }\n.et-l--post .cc-media-prose__identity span { display: block; margin-top: 8px; font-family: var(--font-body); font-size: 13px; line-height: 1.4; font-weight: 500; }\n.et-l--post .cc-media-prose__figure figcaption { font-family: var(--font-body); font-size: var(--t-meta-size); font-weight: 500; line-height: 1.55; margin-top: var(--s-3); color: var(--ink); }\n.et-l--post .cc-media-prose__figure figcaption:empty { display: none; }\n.et-l--post .cc-media-prose .cc-media-prose__body { grid-area: body; min-width: 0; padding: 0; max-width: 65ch; overflow-wrap: break-word; }\n.et-l--post .cc-media-prose__body > .bk-prose__lead:empty { display: none; }\n.et-l--post .cc-media-prose__body > p:last-child:has(> em:first-child) { border-top: 1px solid var(--line); padding-top: var(--s-5); margin-top: var(--s-6); font-size: 13px; font-weight: 500; }\n.et-l--post .cc-media-prose__body > p:last-child > em:first-child { display: inline-block; font-family: var(--font-display); font-size: clamp(28px, 3vw, 34px); font-weight: 500; margin-bottom: 8px; }\n.et-l--post .cc-media-prose.bk-section:not(.bk-section--quiet):not(.bk-section--loud) .bk-h2 { font-size: var(--t-h2-size) !important; }\n@media (max-width: 759px) {\n  .et-l--post .cc-media-prose__layout { grid-template-columns: minmax(0, 1fr); grid-template-areas: \"media\" \"heading\" \"body\"; gap: var(--s-5); }\n  .et-l--post .cc-media-prose__figure { position: static; }\n  .et-l--post .cc-media-prose__heading { max-width: 24ch; }\n  .et-l--post .cc-media-prose.bk-section:not(.bk-section--quiet):not(.bk-section--loud) .bk-h2 { font-size: clamp(28px, 3vw, 34px) !important; }\n}\n\n\/* nav.css -- the site header, in all THREE states.\n   GLOBAL COMPONENT. Divi's theme header; its CSS is authored in the WordPress\n   Customizer, not in this repo. Captured 2026-09-13 from the live cascade in the order\n   the browser applies it: Divi theme defaults, then the site's compiled overrides, then\n   the Customizer block. Rules are grouped by source below and left in that order, so the\n   last declaration for any selector is the one that actually wins.\n\n   THE THREE STATES -- this is what \"the nav in both colours\" means, and there are three:\n     1. over the hero    #main-header:not(.et-fixed-header)\n                         transparent with a top-down black gradient scrim; menu text\n                         --ivory; logo inverted to white via filter:brightness(0) invert(1).\n     2. scrolled         #main-header.et-fixed-header\n                         Divi's solid treatment, dark text, logo un-inverted.\n     3. mobile menu open #main-header:has(.mobile_nav.opened)\n                         background --warm-white #FCF8F0, hamburger --ink, logo un-inverted.\n\n   A REAL CASCADE CONFLICT, recorded rather than resolved silently: the site bundle sets\n     #main-header:not(.et-fixed-header) #top-menu li a { color:#141210!important }   (2,1,2)\n   and the Customizer block sets\n     body[class] #main-header:not(.et-fixed-header) #top-menu li a { color:#F9F0E0!important }  (2,2,3)\n   Both carry !important; the Customizer selector is more specific, so IVORY wins and the\n   nav reads light over the photo hero. Removing the body[class] prefix would silently\n   flip every hero nav to dark text.\n\n   \u26a0 LIVE DEFECT FOUND BY RENDERING THIS, 2026-09-13 -- the logo disappears when the\n   mobile menu is open. Mechanism, confirmed against the cascade below:\n\n     the Customizer's last filter rule is\n        body #main-header:not(.et-fixed-header) .logo_container img,\n        body #main-header:not(.et-fixed-header) #logo\n        { filter: brightness(0) invert(1) !important }\n     and `#logo` is a <picture> ELEMENT, not the <img>. Every un-invert rule --\n     including the mobile-open one -- targets `#logo img`, the CHILD. A filter on a\n     parent establishes a containing rendering context; `filter:none` on the child\n     cannot cancel it.\n\n   Opening the mobile menu does not add .et-fixed-header, so :not(.et-fixed-header)\n   still matches: the header ground correctly turns --warm-white #FCF8F0 while the\n   logo stays inverted WHITE on it. On phones, which are ~95% of this site's traffic.\n\n   The fix belongs in the Customizer, not here: either drop `#logo` from the invert\n   selector so only `.logo_container img` is filtered, or add `#logo` (not `#logo img`)\n   to the mobile-open un-invert rule. This file transcribes what is live and must keep\n   showing the defect until the Customizer is changed.\n\n   KNOWN DEFECT, live: the Customizer block ends with FOUR stacked CC-NAV-END markers.\n   That is the marker-duplication bug already on record (WP normalises an escaped\n   forward slash back to a bare one, and the\n   marker match stacks). Left as-is here because this file transcribes what is live; fix\n   it in the Customizer, not by editing this file.\n\n   The marker names above and below are written WITHOUT their comment delimiters on\n   purpose. CSS comments do not nest: spelling a marker in full closed this comment\n   early, and everything after it became stray text that the parser glued onto the\n   next selector and discarded. Same family as the stray-terminator bug in base.css\n   (a token name ending in a hyphen-star, followed by a slash), and invisible for the\n   same reason -- nothing raises, the rule simply stops existing. Writing THAT token\n   out in full here re-broke this very comment on the first attempt, which is the\n   most direct evidence available that prose about the bug is not a substitute for a\n   gate against it.\n   Caught 2026-09-14, when the parse gate began comparing the authored block count\n   to the parsed one instead of asserting `> 250`. *\/\n\n\/* ---- from Divi theme defaults (et-core-unified-tb-194807-874.min.css) ---- *\/\n#et_search_icon:hover,\n.mobile_menu_bar:before,\n.mobile_menu_bar:after,\n.et_toggle_slide_menu:after,\n.et-social-icon a:hover,\n.et_pb_sum,\n.et_pb_pricing li a,\n.et_pb_pricing_table_button,\n.et_overlay:before,\n.entry-summary p.price ins,\n.et_pb_member_social_links a:hover,\n.et_pb_widget li a:hover,\n.et_pb_filterable_portfolio .et_pb_portfolio_filters li a.active,\n.et_pb_filterable_portfolio .et_pb_portofolio_pagination ul li a.active,\n.et_pb_gallery .et_pb_gallery_pagination ul li a.active,\n.wp-pagenavi span.current,\n.wp-pagenavi a:hover,\n.nav-single a,\n.tagged_as a,\n.posted_in a {\n  color:#ffffff;\n}\n.et-search-form,\n.nav li ul,\n.et_mobile_menu,\n.footer-widget li:before,\n.et_pb_pricing li:before,\nblockquote {\n  border-color:#ffffff;\n}\n#main-header,\n#main-header .nav li ul,\n.et-search-form,\n#main-header .et_mobile_menu {\n  background-color:rgba(255,255,255,0.8);\n}\n.et_header_style_centered .mobile_nav .select_page,\n.et_header_style_split .mobile_nav .select_page,\n.et_nav_text_color_light #top-menu>li>a,\n.et_nav_text_color_dark #top-menu>li>a,\n#top-menu a,\n.et_mobile_menu li a,\n.et_nav_text_color_light .et_mobile_menu li a,\n.et_nav_text_color_dark .et_mobile_menu li a,\n#et_search_icon:before,\n.et_search_form_container input,\nspan.et_close_search_field:after,\n#et-top-navigation .et-cart-info {\n  color:#0a0a0a;\n}\n#main-header .nav li ul a {\n  color:#ffffff;\n}\n#top-menu li a,\n.et_search_form_container input {\n  font-weight:bold;\n  font-style:normal;\n  text-transform:uppercase;\n  text-decoration:none;\n  letter-spacing:5px;\n}\n#top-menu li.current-menu-ancestor>a,\n#top-menu li.current-menu-item>a,\n#top-menu li.current_page_item>a {\n  color:#0a0a0a;\n}\n#main-header {\n  box-shadow:none;\n}\n#main-header,\n#et-top-navigation {\n  font-family:'Josefin Sans',sans-serif;\n}\n\n\/* ---- from site overrides (et-core-unified-874.min.css) ---- *\/\n#main-header {\n  position:fixed!important;\n  top:0!important;\n  left:0;\n  right:0;\n  width:100%!important;\n  z-index:99999!important;\n  box-shadow:none!important;\n  border-bottom:1px solid transparent!important;\n  transition:background .35s,backdrop-filter .35s,box-shadow .35s,border-color .35s,color .3s!important;\n}\nbody.et_pb_pagebuilder_layout #main-header:not(.et-fixed-header) {\n  background:transparent!important;\n  background-color:transparent!important;\n}\nbody.et_pb_pagebuilder_layout #main-header:has(.mobile_nav.opened) {\n  background:#FCF8F0!important;\n  background-color:#FCF8F0!important;\n}\nbody.et_pb_pagebuilder_layout #main-header:has(.mobile_nav.opened) .logo_container #logo img {\n  filter:none!important;\n}\nbody.et_pb_pagebuilder_layout #main-header:has(.mobile_nav.opened) .mobile_menu_bar:before {\n  color:#141210!important;\n}\n#main-header:not(.et-fixed-header) #top-menu li a {\n  color:#141210!important;\n}\n#main-header:not(.et-fixed-header) .mobile_menu_bar:before {\n  color:#141210!important;\n}\nbody.page-id-874 #main-header:not(.et-fixed-header) #top-menu li a,\nbody.page-id-192 #main-header:not(.et-fixed-header) #top-menu li a,\nbody.page-id-192218 #main-header:not(.et-fixed-header) #top-menu li a {\n  color:#FFFFFF!important;\n}\nbody.page-id-874 #main-header:not(.et-fixed-header) .mobile_menu_bar:before,\nbody.page-id-192 #main-header:not(.et-fixed-header) .mobile_menu_bar:before,\nbody.page-id-192218 #main-header:not(.et-fixed-header) .mobile_menu_bar:before {\n  color:#FFFFFF!important;\n}\n#main-header .logo_container #logo img {\n  filter:none!important;\n}\nbody.page-id-874 #main-header:not(.et-fixed-header) .logo_container #logo img,\nbody.page-id-192 #main-header:not(.et-fixed-header) .logo_container #logo img,\nbody.page-id-192218 #main-header:not(.et-fixed-header) .logo_container #logo img {\n  filter:brightness(0) invert(1)!important;\n}\n#main-header.et-fixed-header .logo_container #logo img,\n#main-header:has(.mobile_nav.opened) .logo_container #logo img {\n  filter:none!important;\n}\nbody.et_pb_pagebuilder_layout #main-header.et-fixed-header {\n  background:#FCF8F0!important;\n  background-color:#FCF8F0!important;\n  -webkit-backdrop-filter:blur(12px);\n  backdrop-filter:blur(12px);\n  border-bottom:1px solid rgba(20,18,16,.12)!important;\n  box-shadow:0 6px 24px rgba(11,10,9,.06)!important;\n}\n#main-header.et-fixed-header #top-menu li a {\n  color:#141210!important;\n}\n#main-header.et-fixed-header .mobile_menu_bar:before {\n  color:#141210!important;\n}\n#main-header .container.et_menu_container,\n#main-header.et-fixed-header .container.et_menu_container {\n  display:flex!important;\n  align-items:center!important;\n  justify-content:space-between!important;\n  position:relative!important;\n  height:70px!important;\n  min-height:70px!important;\n  max-height:70px!important;\n  padding-top:0!important;\n  padding-bottom:0!important;\n  max-width:1340px!important;\n}\n.logo_container,\n#main-header.et-fixed-header .logo_container {\n  position:static!important;\n  height:70px!important;\n  display:flex!important;\n  align-items:center!important;\n  width:auto!important;\n  margin:0!important;\n  flex:0 0 auto!important;\n}\n#main-header .logo_container #logo img,\n#main-header.et-fixed-header .logo_container #logo img {\n  height:36px!important;\n  max-height:36px!important;\n  width:auto!important;\n}\n#logo,\n#main-header.et-fixed-header #logo {\n  max-height:36px!important;\n}\n#main-header #et-top-navigation,\n#main-header.et-fixed-header #et-top-navigation {\n  padding:0!important;\n  margin:0!important;\n  display:flex!important;\n  align-items:center!important;\n  height:70px!important;\n}\n\/* Preserve HOME's mobile alignment after the shared margin reset above.\n   Divi's clearfix ::after is a third flex item: space-between alone leaves the\n   menu in the middle. The auto margin consumes that gap and retains the gutter. *\/\n@media (max-width:980px) {\n  #main-header #et-top-navigation,\n  #main-header.et-fixed-header #et-top-navigation {\n    margin-left:auto!important;\n  }\n  \/* The fixed header above is 70px tall. Keep every menu link reachable\n     in landscape and zoomed layouts without changing Divi's slide behavior. *\/\n  #main-header .et_mobile_menu {\n    box-sizing:border-box;\n    max-height:calc(100vh - 70px);\n    max-height:calc(100dvh - 70px);\n    overflow-y:auto;\n    overscroll-behavior:contain;\n  }\n}\n#main-header #top-menu li a {\n  font-family:'Montserrat',sans-serif!important;\n  font-size:13px!important;\n  font-weight:600!important;\n  letter-spacing:.16em!important;\n  text-transform:uppercase!important;\n  padding:0!important;\n  line-height:1!important;\n}\n#main-header #top-menu li.menu-item-392 a {\n  background:#0B0A09!important;\n  color:#F9F0E0!important;\n  padding:11px 22px!important;\n  font-size:12px!important;\n  line-height:1.1!important;\n}\n#main-header #top-menu li.menu-item-392 a:hover {\n  opacity:.88!important;\n}\n#main-header #top-menu li.current-menu-item>a,\n#main-header #top-menu li.current_page_item>a,\nbody.home #main-header #top-menu li.menu-item-249>a {\n  text-decoration:underline!important;\n  text-underline-offset:7px!important;\n  text-decoration-thickness:1.5px!important;\n  text-decoration-color:currentColor!important;\n}\n.mobile_menu_bar:before {\n  font-size:32px!important;\n  line-height:1!important;\n}\n#main-header .wpml-ls-menu-item .wpml-ls-native {\n  font-size:0!important;\n  letter-spacing:0!important;\n}\n#main-header .wpml-ls-item-en>a .wpml-ls-native::after {\n  content:\"EN\";\n  font-size:var(--t-ui-size);\n  letter-spacing:1.92px;\n}\n#main-header .wpml-ls-item-es>a .wpml-ls-native::after {\n  content:\"ES\";\n  font-size:var(--t-ui-size);\n  letter-spacing:1.92px;\n}\n#main-header .wpml-ls-menu-item.menu-item-has-children>a::after {\n  display:none!important;\n}\n#main-header .wpml-ls-item-en.wpml-ls-current-language>a .wpml-ls-native::after {\n    \/* Literal NBSP (U+00A0) and U+25BE, deliberately NOT the CSS hex escapes.\n     A CSS hex escape needs a backslash, Divi block JSON then carries that as a\n     DOUBLE backslash, and preflight check_divi_comment_transport blocks it:\n     WordPress rewrites backslashes on save -- the same normalisation that\n     stacked duplicate blocks on \/tour\/. Measured 2026-09-15 against the live\n     stored document: 1022 hyphen-escapes, 653 lt-escapes, 1320 quote-escapes,\n     and ZERO backslash escapes of any kind, so these two would have been the\n     first with no round-trip precedent. Literal UTF-8 needs no backslash and\n     the serializer already runs ensure_ascii=False. Do not 'tidy' these back\n     into hex escapes -- that re-blocks every page build. *\/\ncontent:\"EN\u00a0\u25be\";\n}\n#main-header .wpml-ls-item-es.wpml-ls-current-language>a .wpml-ls-native::after {\n  content:\"ES\u00a0\u25be\";\n}\n#main-header .wpml-ls-menu-item .wpml-ls-display {\n  display:none!important;\n}\n\n\/* The selected language must read as selected. The former mobile rule dimmed the\n   current locale to 42%, which made the alternate language look active. Keep a\n   non-colour indicator so the state remains clear without relying on contrast alone.\n   SUPERSEDED 2026-10-02 (owner): the 600 weight and the 1px line below are overridden on desktop and phone by the\n   \"language you are on\" blocks further down (700 + the selected page's underline on the letters). Kept because it\n   records the site's live compiled CSS. *\/\n#main-header .wpml-ls-current-language>a {\n  opacity:1!important;\n  font-weight:600!important;\n  position:relative;\n}\n#main-header .wpml-ls-current-language>a::before {\n  content:\"\";\n  position:absolute;\n  left:0;\n  right:0;\n  bottom:10px;\n  height:1px;\n  background:currentColor;\n}\n#main-header .wpml-ls-current-language>.sub-menu a {\n  font-weight:500!important;\n  opacity:.78!important;\n}\n@media (max-width:980px) {\n  #main-header #mobile_menu>.wpml-ls-current-language>a::before { bottom:13px; }\n  #main-header #mobile_menu>.wpml-ls-current-language>.sub-menu a {\n    color:var(--graphite)!important;\n  }\n}\n\n\/* ---- from Customizer, inline (the CC-NAV-START block) ---- *\/\nbody.et_pb_pagebuilder_layout #main-header:not(.et-fixed-header) {\n  background-image:linear-gradient(180deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,.26) 50%,rgba(0,0,0,0) 85%)!important;\n  background-repeat:no-repeat!important;\n  background-size:100% 100%!important;\n  background-color:transparent!important;\n  border-bottom-color:transparent!important;\n}\nbody[class] #main-header:not(.et-fixed-header) #top-menu li a {\n  color:#F9F0E0!important;\n}\nbody[class] #main-header:not(.et-fixed-header) #top-menu>li.menu-item-392>a {\n  color:#F9F0E0!important;\n}\nbody[class] #main-header:not(.et-fixed-header) .mobile_menu_bar:before {\n  color:#F9F0E0!important;\n}\nbody #main-header:not(.et-fixed-header) .logo_container img,\nbody #main-header:not(.et-fixed-header) #logo {\n  filter:brightness(0) invert(1)!important;\n}\n#main-header .et_mobile_menu li.menu-item-has-children > ul.sub-menu {\n  display: block !important;\n  visibility: visible !important;\n}\n#main-header .et_mobile_menu li.menu-item-has-children > a:after {\n  content: '' !important;\n}\n\n@media (min-width: 981px) {\n  \/* The existing language controller opens with Enter\/Space via aria-expanded. *\/\n  #main-header #top-menu .wpml-ls-menu-item > a[aria-expanded=\"true\"] + ul.sub-menu {\n    visibility: visible;\n    opacity: 1;\n  }\n}\n\n\/* Phase 2: declared hero context. The captured, unannotated header above remains\n   unchanged. One existing Divi fixed\/open state drives both foreground variants;\n   an unknown authored context receives the readable solid treatment below.\n   Keep the logo filter on its image only: filtering picture AND image inverts it\n   twice. No image sampling, scroll controller or second click owner is needed. *\/\nbody[class] #main-header[data-cc-nav-context] {\n  --cc-nav-foreground:var(--ink);\n  --cc-nav-logo-filter:none;\n  background:var(--warm-white)!important;\n  background-image:none!important;\n  border-bottom-color:var(--line)!important;\n}\nbody[class] #main-header[data-cc-nav-context=\"light\"]:not(.et-fixed-header):not(:has(.mobile_nav.opened)) {\n  background:transparent!important;\n  border-bottom-color:transparent!important;\n}\nbody[class] #main-header[data-cc-nav-context=\"media\"]:not(.et-fixed-header):not(:has(.mobile_nav.opened)) {\n  --cc-nav-foreground:var(--ivory);\n  --cc-nav-logo-filter:brightness(0) invert(1);\n  background:linear-gradient(180deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,.26) 50%,rgba(0,0,0,0) 85%)!important;\n  background-repeat:no-repeat!important;\n  background-size:100% 100%!important;\n  border-bottom-color:transparent!important;\n}\nbody[class] #main-header[data-cc-nav-context] #top-menu li a,\nbody[class] #main-header[data-cc-nav-context] .mobile_menu_bar:before {\n  color:var(--cc-nav-foreground)!important;\n}\nbody[class] #main-header[data-cc-nav-context] #logo {\n  filter:none!important;\n}\nbody[class] #main-header[data-cc-nav-context] .logo_container #logo img {\n  filter:var(--cc-nav-logo-filter)!important;\n}\nbody[class] #main-header[data-cc-nav-context] .logo_container>a,\nbody[class] #main-header[data-cc-nav-context] #top-menu li a {\n  display:flex;\n  align-items:center;\n  min-width:44px;\n  min-height:44px;\n}\nbody[class] #main-header[data-cc-nav-context] .mobile_menu_bar {\n  display:grid;\n  place-items:center;\n  width:44px;\n  height:44px;\n  line-height:1;\n  appearance:none;\n  padding:0;\n  border:0;\n  border-radius:0;\n  background:transparent;\n  color:var(--cc-nav-foreground);\n  font:inherit;\n}\nbody[class] #main-header[data-cc-nav-context] .mobile_menu_bar:before {\n  content:'';\n  width:20px;\n  height:2px;\n  background:currentColor;\n  box-shadow:0 -6px 0 currentColor,0 6px 0 currentColor;\n}\n\/* The close X is drawn, not typed (owner 2026-10-02: \"the x is closer to the bottom of the section vs the middle\").\n   The glyph U+00D7 sat in a 24px box whose line box Divi's icon rule holds at 32px (font-size and line-height both\n   important), so it drew about 10px below the header's centre line. Two 2px diagonals in an 18px square, centred by\n   the 44px grid button exactly like the hamburger's bars. No font can move it. *\/\nbody[class] #main-header[data-cc-nav-context]:has(.mobile_nav.opened) .mobile_menu_bar:before {\n  content:'';\n  width:18px;\n  height:18px;\n  background:linear-gradient(45deg,transparent calc(50% - 1px),currentColor calc(50% - 1px),currentColor calc(50% + 1px),transparent calc(50% + 1px)),linear-gradient(-45deg,transparent calc(50% - 1px),currentColor calc(50% - 1px),currentColor calc(50% + 1px),transparent calc(50% + 1px));\n  box-shadow:none;\n}\nbody[class] #main-header[data-cc-nav-context] #top-menu .sub-menu li a {\n  color:var(--ink)!important;\n}\nbody[class] #main-header[data-cc-nav-context] #top-menu>li.menu-item-392>a,\nbody[class] #main-header[data-cc-nav-context] .et_mobile_menu>li.menu-item-392>a {\n  background:var(--accent)!important;\n  color:var(--ivory)!important;\n}\nbody[class] #main-header[data-cc-nav-context] #top-menu>li.menu-item-392>a:is(:hover,:focus-visible),\nbody[class] #main-header[data-cc-nav-context] .et_mobile_menu>li.menu-item-392>a:is(:hover,:focus-visible) {\n  background:#8D8175!important;\n  color:var(--accent)!important;\n  opacity:1!important;\n}\n@media (min-width:981px) {\n  #main-header[data-cc-nav-context] #top-menu .wpml-ls-current-language>.sub-menu {\n    left:auto;\n    right:0;\n  }\n  \/* An explicit closed state wins over Divi's hover\/focus-within fallback.\n     Otherwise Escape returns focus but leaves the language panel visible. *\/\n  #main-header[data-cc-nav-context] #top-menu .wpml-ls-menu-item>a[aria-expanded=\"false\"]+.sub-menu {\n    display:none;\n  }\n}\n\n\/* The page you are on, in the header (owner 2026-10-02: \"the selection while underlined its not clear, it should\n   also be bolded and underline\"). Desktop items are Montserrat 600, so the selected one steps to 700 (a face the site\n   loads) and keeps HOME's underline. The phone menu asked for 'Josefin Sans', which the site never loads; iPhones drew\n   Helvetica, whose 600 is already bold, so a weight step could not show. It now draws in the system's Montserrat 600\n   like the desktop menu, and the selected item is 700 and underlined. The Book Now button is never marked.\n   Sitewide: these same rules go in the Customizer for pages the system does not own yet. *\/\nbody[class] #main-header #top-menu>li:is(.current-menu-item,.current_page_item):not(.menu-item-392)>a,\nbody.home[class] #main-header #top-menu>li.menu-item-249>a {\n  font-weight:700!important;\n  text-decoration:underline!important;\n  text-underline-offset:7px!important;\n  text-decoration-thickness:1.5px!important;\n}\nbody[class] #main-header .et_mobile_menu>li>a {\n  font-family:'Montserrat',sans-serif!important;\n  font-weight:600!important;\n}\nbody[class] #main-header .et_mobile_menu>li:is(.current-menu-item,.current_page_item):not(.menu-item-392)>a,\nbody.home[class] #main-header .et_mobile_menu>li.menu-item-249>a {\n  font-weight:700!important;\n  text-decoration:underline!important;\n  text-underline-offset:6px!important;\n  text-decoration-thickness:1.5px!important;\n}\n\nbody[class] #main-header .et_mobile_menu>li:is(.current-menu-item,.current_page_item):not(.menu-item-392)>a,\nbody.home[class] #main-header .et_mobile_menu>li.menu-item-249>a {\n  position:relative;\n}\n\/* The phone menu's arrow is the link's in-flow ::after (block, margin-left:auto inside 26px of right padding), so the\n   underline would run under it too. Out of flow it is not decorated; pinned exactly where flex placed it. *\/\nbody[class] #main-header .et_mobile_menu>li:is(.current-menu-item,.current_page_item):not(.menu-item-392)>a::after,\nbody.home[class] #main-header .et_mobile_menu>li.menu-item-249>a::after {\n  position:absolute;\n  top:0;\n  bottom:0;\n  right:26px;\n  margin:0;\n  display:flex;\n  align-items:center;\n}\n\n\/* The language you are on, in the phone menu. Measured live 2026-10-02: the theme's two-id rule\n   (#main-header #mobile_menu > li.wpml-ls-menu-item > a, opacity .42 important) beat the one-id system rule above,\n   so the current language showed at 42% and the other at full ink -- it read as if the other one were selected.\n   Same mark as the selected page: full ink, 700, underlined (the 1px line above is replaced, not doubled). *\/\n@media (max-width:980px) {\n  body[class] #main-header #mobile_menu>li.wpml-ls-menu-item a {\n    font-family:'Montserrat',sans-serif!important;\n  }\n  body[class] #main-header #mobile_menu>li.wpml-ls-current-language>a {\n    opacity:1!important;\n    font-weight:700!important;\n    color:var(--ink)!important;\n    text-decoration:underline!important;\n    text-underline-offset:6px!important;\n    text-decoration-thickness:1.5px!important;\n  }\n  body[class] #main-header #mobile_menu>li.wpml-ls-current-language>a::before {\n    content:none!important;\n  }\n  \/* Owner 2026-10-02 round 4: \"also translator switch on mobile nav bolded\". The other language was 500 at 0.78 in\n     graphite and read faint beside the 600 menu; it now matches the menu items. The current one keeps 700 + underline. *\/\n  body[class] #main-header #mobile_menu>li.wpml-ls-current-language>.sub-menu a {\n    font-weight:600!important;\n    opacity:1!important;\n    color:var(--ink)!important;\n  }\n}\n\n\/* The language you are on, beside the logo on desktop. Owner 2026-10-02, second round: \"did not do the selected\n   bolded for en and es\". It stayed 600 like every item, marked only by the 1px line above, drawn 10px over the link's\n   bottom edge and well under the letters. It now takes the selected page's mark: 700 and the same underline. The label\n   and its arrow were one pseudo (\"EN \u25be\"), so an underline would have run under the arrow; the arrow moves to the span's\n   own ::before, placed after the letters by flex order and left undecorated (the span is inline-flex, an atomic box,\n   so nothing from the link's own decoration reaches it either). *\/\n@media (min-width:981px) {\n  body[class] #main-header #top-menu>li.wpml-ls-current-language>a {\n    font-weight:700!important;\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-current-language>a::before {\n    content:none!important;\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-current-language>a .wpml-ls-native {\n    display:inline-flex;\n    align-items:baseline;\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-item-en.wpml-ls-current-language>a .wpml-ls-native::after {\n    content:\"EN\";\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-item-es.wpml-ls-current-language>a .wpml-ls-native::after {\n    content:\"ES\";\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-current-language>a .wpml-ls-native::after {\n    text-decoration:underline!important;\n    text-underline-offset:7px!important;\n    text-decoration-thickness:1.5px!important;\n  }\n  body[class] #main-header #top-menu>li.wpml-ls-current-language>a .wpml-ls-native::before {\n    content:\"\u00a0\u25be\";\n    order:1;\n    font-size:var(--t-ui-size);\n    letter-spacing:1.92px;\n    text-decoration:none;\n  }\n}\n\n\/* Shared measured clearance for context-aware plain heroes and topic anchors. *\/\n:root { --cc-header-height: 71px; }\n\n\/* Phase 2: membership-first offer with a related question form, not hourly rates. *\/\n.et-l--post .cc-offer__heading { text-align:center; margin-bottom:var(--s-6); }\n.et-l--post .cc-offer__layout { display:grid; gap:var(--s-7); padding:var(--s-5); border:1px solid var(--line); background:var(--warm-white); }\n.et-l--post :is(.cc-offer__detail,.cc-offer__inquiry) { min-width:0; }\n.et-l--post .cc-offer__price { display:flex; align-items:baseline; flex-wrap:wrap; gap:var(--s-2); margin:0; padding:0; }\n.et-l--post .cc-offer__price strong { font:700 clamp(52px,9vw,72px)\/1 var(--font-body); letter-spacing:-.035em; }\n.et-l--post .cc-offer__price span { font:500 16px\/1.5 var(--font-body); }\n.et-l--post .cc-offer__savings { font:500 12px\/1.6 var(--font-body); border:1px solid var(--line); padding:var(--s-3) var(--s-4); margin:var(--s-4) 0 var(--s-5); }\n.et-l--post .cc-offer__intro { font:500 16px\/1.7 var(--font-body); margin:0; padding:0; }\n.et-l--post .cc-offer__features { display:grid; gap:var(--s-5); margin:var(--s-5) 0; padding:var(--s-5) 0 0; border-top:1px solid var(--line); list-style:none; }\n.et-l--post .cc-offer__features h3 { font:600 16px\/1.5 var(--font-body); padding:0; margin:0 0 var(--s-1); }\n.et-l--post .cc-offer__features p { font:400 14px\/1.65 var(--font-body); padding:0; margin:0; color:var(--graphite); }\n.et-l--post .cc-offer__action .btn { display:flex; width:100%; justify-content:center; text-align:center; white-space:normal; }\n.et-l--post .cc-offer__inquiry { border-top:1px solid var(--line); padding-top:var(--s-6); }\n@media (min-width:980px) {\n .et-l--post .cc-offer__layout { grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--s-8); padding:var(--s-7); }\n .et-l--post .cc-offer__inquiry { border-top:0; padding-top:0; }\n .et-l--post .cc-offer .cc-form__fields { grid-template-columns:repeat(2,minmax(0,1fr)); }\n .et-l--post .cc-offer :is(.cc-field--name,.cc-field--message) { grid-column:1\/-1; }\n}\n\n\/* Original featured gallery geometry and controls, measured at 320\u20131440px.\n   Owner's sole visual change: the section ground now uses approved ivory. *\/\n.et-l--post .cc-portfolio {padding:0!important;background:var(--ivory)!important;-webkit-font-smoothing:antialiased}\n.et-l--post .cc-portfolio [hidden] {display:none!important}\n.et-l--post .cc-portfolio .gal-bar {background:var(--ivory)}\n.et-l--post .cc-portfolio .gal-bar__in {width:min(1240px,100%);margin:0 auto;padding:clamp(20px,3vw,30px) clamp(20px,5vw,54px) clamp(26px,3.6vw,36px);display:flex;align-items:center;justify-content:space-between;gap:18px}\n.et-l--post .cc-portfolio .gtabs {display:flex;gap:10px;overflow-x:auto;scrollbar-width:none}\n.et-l--post .cc-portfolio .gtabs::-webkit-scrollbar {display:none}\n.et-l--post .cc-portfolio .gal-tab {flex:0 0 auto;white-space:nowrap;font-family:var(--font-body);font-size:12px;font-weight:600;line-height:normal;letter-spacing:.04em;padding:9px 15px;border:1px solid rgba(20,18,16,.14);border-radius:0;background:transparent;color:#141210;cursor:pointer;transition:background .2s,color .2s,border-color .2s;min-height:44px}\n.et-l--post .cc-portfolio .gal-tab:hover {border-color:#000}\n.et-l--post .cc-portfolio .gal-tab.is-sel {background:#000;color:#F9F0E0;border-color:#000}\n.et-l--post .cc-portfolio .gal-bar__cta {flex:0 0 auto}\n.et-l--post .cc-portfolio .gal-bar__cta .btn {display:inline-flex;align-items:center;gap:.6em;font-family:var(--font-body);font-weight:600;font-size:12px;line-height:25.2px;letter-spacing:.12em;text-transform:uppercase;padding:16px 30px;background:#0B0A09;color:#F9F0E0;border:1px solid #0B0A09;border-radius:0;text-decoration:none;transition:background .2s}\n.et-l--post .cc-portfolio .gal-bar__cta .btn:hover {background:#8D8175;border-color:#8D8175}\n.et-l--post .cc-portfolio-source-arrow {font-family:serif}\n.et-l--post .cc-portfolio .gal-grid-row {display:flex;width:100%;max-width:100%;margin:0;padding:0}\n.et-l--post .cc-portfolio-column {width:29.66666667%;margin-right:5.5%;min-width:0}\n.et-l--post .cc-portfolio-column:last-child {margin-right:0}\n.et-l--post .cc-portfolio .gal-item {margin:8px;padding:0}\n.et-l--post .cc-portfolio-open {display:block;line-height:0}\n.et-l--post .cc-portfolio-open img {display:block;width:100%;height:auto}\n@media(max-width:980px){.et-l--post .cc-portfolio-column {width:33.33333333%;margin:0 0 30px}.et-l--post .cc-portfolio-column:last-child {margin:0}}\n@media(max-width:767px){.et-l--post .cc-portfolio .gal-item {margin:5px}}\n@media(max-width:720px){.et-l--post .cc-portfolio .gal-bar__in {padding-top:16px;padding-bottom:22px}.et-l--post .cc-portfolio .gal-bar__cta {display:none}}\n@media(prefers-reduced-motion:reduce){.et-l--post .cc-portfolio .gal-tab,.et-l--post .cc-portfolio .gal-bar__cta .btn {transition:none}}\n\n\/* press.css \u2014 HOME's \"as seen in\" logo marquee (.ccp-press), extracted\n   verbatim from reference\/home.css (offset ~57075) and confirmed against\n   the identical inline <style> block inside the live page's press\n   section in scratchpad\/home.html. Unlike almost everything else mined\n   for this system, HOME ships this CSS completely UNSCOPED \u2014 no\n   .et-l--post prefix anywhere in the source, because it comes from a\n   page-local Code-module <style> tag, not the sitewide Additional CSS \u2014\n   so every selector below is scoped here for the first time, per the\n   project's rule. One declaration found for each selector (enumerated\n   every literal occurrence in reference\/home.css, not just the first\n   match, including inside both @media blocks) \u2014 no cascade conflicts.\n\n   Search-before-concluding: scratchpad\/home.html's inline JS was\n   searched for \"ccp-\" and has no hits, confirming the marquee is\n   CSS-only \u2014 .ccp-track's motion is a pure @keyframes animation, no\n   toggle\/JS behaviour to extract here, unlike faq\/sticky.\n\n   @keyframes ccp-scroll lives in base.css, not here, for the same\n   reason @keyframes hmmarquee does (see base.css's own comment on it):\n   its from\/to percentage selectors cannot be prefixed with .et-l--post,\n   and this file IS covered by the per-component scoping test, so a bare\n   from or to selector here would fail it.\n\n   Mobile refinement (offset ~111527, inside reference\/home.css's\n   @media (max-width:760px) block, single declaration, no conflicting\n   duplicate elsewhere): HOME tightens this section's top padding and\n   widens its bottom padding so it sits close under the reviews section\n   above it \u2014 the reviews-side counterpart of this same pairing lives in\n   reviews.css. *\/\n.et-l--post .ccp-press {\n  position: relative;\n  left: 50%;\n  right: 50%;\n  width: 100vw;\n  max-width: 100vw;\n  margin-left: -50vw;\n  margin-right: -50vw;\n  padding: 0;\n  box-sizing: border-box;\n  overflow: hidden;\n}\n.et-l--post .ccp-marquee {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);\n  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);\n}\n.et-l--post .ccp-track {\n  display: flex;\n  align-items: center;\n  gap: clamp(40px, 6vw, 74px);\n  width: max-content;\n  animation: ccp-scroll 50s linear infinite;\n  will-change: transform;\n}\n.et-l--post .ccp-marquee:hover .ccp-track {\n  animation-play-state: paused;\n}\n\/* Keyboard focus exposes one stationary, horizontally scrollable sequence. *\/\n.et-l--post .ccp-marquee:focus-within {\n  overflow-x: auto;\n  scroll-padding-inline: 8px;\n  -webkit-mask-image: none;\n  mask-image: none;\n}\n.et-l--post .ccp-marquee:focus-within .ccp-track {\n  animation: none;\n  transform: none;\n  padding-inline: 8px;\n}\n.et-l--post .ccp-marquee:focus-within [aria-hidden=\"true\"] {\n  display: none;\n}\n.et-l--post .ccp-marquee:not([data-cc-press-ready]):focus-within .ccp-track {\n  width: 100%;\n  flex-wrap: wrap;\n  justify-content: center;\n}\n.et-l--post .ccp-logo {\n  flex: 0 0 auto;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  text-decoration: none;\n}\n.et-l--post .ccp-logo img {\n  width: auto;\n  display: block;\n  opacity: .62;\n  transition: opacity .25s cubic-bezier(.22,1,.36,1), transform .25s cubic-bezier(.22,1,.36,1);\n}\n.et-l--post a.ccp-logo:hover img,\n.et-l--post a.ccp-logo:focus-visible img {\n  opacity: 1;\n  transform: translateY(-1px);\n}\n.et-l--post a.ccp-logo:focus-visible {\n  outline: 2px solid #8D8175;\n  outline-offset: 6px;\n}\n.et-l--post .ccp-badge img {\n  opacity: .72;\n}\n@media (max-width: 980px) {\n  .et-l--post .ccp-track {\n    animation-duration: 38s;\n  }\n  .et-l--post .ccp-logo img {\n    transform: scale(.82);\n  }\n  .et-l--post a.ccp-logo:hover img {\n    transform: scale(.82) translateY(-1px);\n  }\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .ccp-marquee {\n    -webkit-mask-image: none;\n    mask-image: none;\n  }\n  .et-l--post .ccp-track {\n    animation: none;\n    flex-wrap: wrap;\n    justify-content: center;\n    width: 100%;\n    gap: 28px 46px;\n    max-width: 1180px;\n    margin: 0 auto;\n    padding: 0 20px;\n  }\n  .et-l--post .ccp-track > [aria-hidden=\"true\"] {\n    display: none;\n  }\n}\n\/* The strip's section edges are derived (`proof` role, spacing.py). The marquee adds\n   no padding of its own, so the logos sit exactly on the section's content edge. *\/\n@media (min-width: 761px) {\n  .et-l--post .ccp-press {\n    padding-top: 0;\n    padding-bottom: 0;\n  }\n}\n\n\/* price.css \u2014 HOME's studio-rate list (.shoot-list \/ .shoot-row). Body\n   extracted verbatim from reference\/home.css by tools\/cc_system\/lift.py; every\n   selector scoped to .et-l--post. Re-run\n   lift.py --classes shoot-list shoot-row shoot-row__name shoot-row__meta\n   shoot-row__use shoot-row__right shoot-row__price rather than editing below.\n\n   Why this component exists: 34 price sections across 24 pages (measured\n   2026-09-13, vocabulary.py) and the system had no price component at all.\n   offer.html sells ONE dominant package; this is the multi-row RATE TABLE.\n   They are different jobs, and conflating them is what produced eight pages\n   whose sticky-bar price contradicts their own rate rows.\n\n   Conflicts, enumerated:\n     .shoot-list \/ .shoot-row \/ .shoot-row__meta \/ .shoot-row__right \/\n     .shoot-row__price   2x each \u2014 base + @media min-760. Above 760px HOME\n                         re-lays each row from a 2-column [name | price] grid\n                         into a single column with the price beneath, and\n                         switches the list itself to 3 columns. Additive by\n                         breakpoint; no conflict.\n     .shoot-row__name    2x \u2014 base font-weight:500; later compound rule wins at\n                         600 !important.\n   No other selector is declared twice.\n\n   Transcribed but inert: `.shoot-row:hover .shoot-row__arrow`. HOME declares\n   the hover transform but ships neither a base rule for .shoot-row__arrow nor\n   any markup using it (searched reference\/home.css and all 54 rendered pages).\n   Kept because it is part of the lifted rule and costs nothing; do not add\n   markup for it without a base rule to go with it. *\/\n.et-l--post .shoot-list {\n  display: grid;\n  gap: 10px;\n  margin-top: 18px;\n}\n\/* Phase 2: standalone package\/comparison lists keep names near their prices.\n   Opt-in content variant; HOME's full-width price composition is unchanged. *\/\n.et-l--post [data-price-measure=\"compact\"] > .container-bk {\n  width: min(752px, 92vw);\n}\n.et-l--post .shoot-list:has(.price-tabs) {\n  display: block;\n}\n.et-l--post .shoot-row {\n  display: grid;\n  grid-template-columns: minmax(0, 1fr) auto;\n  align-items: center;\n  gap: 4px 16px;\n  border: 1px solid var(--line);\n  background: var(--warm-white);\n  padding: 18px 18px;\n  color: inherit;\n  position: relative;\n  transition: border-color .25s, background .25s, transform .25s;\n}\n.et-l--post .shoot-row:hover {\n  border-color: var(--accent);\n  transform: translateY(-1px);\n}\n\/* `.shoot-row__flag` was in the MARKUP and in no stylesheet, so the featured row\n   rendered \"The Signature Most Popular\" as one continuous string -- the badge simply\n   ran on from the name. Caught by the senior-UI seat reading the render; the same\n   declared-but-unapplied pattern as the emphasis layer and the layout families, at the\n   smallest possible scale. Set small, spaced and slightly recessive so it reads as a\n   label on the row rather than part of the product name. *\/\n.et-l--post .shoot-row__flag {\n  display: inline-block;\n  margin-left: 10px;\n  vertical-align: 0.18em;\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 600;\n  letter-spacing: 0.14em;\n  text-transform: uppercase;\n  opacity: 0.72;\n}\n\n.et-l--post .shoot-row--feat {\n  border: 1.5px solid var(--accent);\n}\n.et-l--post .shoot-row__name {\n  grid-column: 1;\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: var(--t-h3-size);\n  line-height: var(--t-h3-lh);\n  display: flex;\n  align-items: baseline;\n  gap: 9px;\n  flex-wrap: wrap;\n}\n.et-l--post .shoot-row__meta {\n  grid-column: 1;\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--graphite);\n  margin-top: 5px;\n  line-height: 1.4;\n}\n.et-l--post .shoot-row__meta b {\n  color: var(--ink);\n  font-weight: 600;\n}\n.et-l--post .shoot-row__use {\n  display: block;\n}\n.et-l--post .shoot-row__right {\n  grid-column: 2;\n  grid-row: 1 \/ span 2;\n  display: flex;\n  align-items: center;\n  gap: 14px;\n}\n.et-l--post .shoot-row__price {\n  font-family: var(--font-body);\n  font-weight: 600;\n  letter-spacing: -0.015em;\n  font-size: var(--t-numeral-size);\n  line-height: var(--t-numeral-lh);\n}\n.et-l--post .shoot-row:hover .shoot-row__arrow {\n  transform: translateX(4px);\n}\n\/* RECORDED DIVERGENCE FROM HOME, 2026-09-14: the ledger stays a ledger at every width.\n\n   HOME breaks this list into `repeat(3, minmax(0,1fr))` above 760px. Three problems,\n   all measured rather than argued:\n\n     1. It contradicts the component's own declared family. direction.json defines\n        `ledger` as \"a list of rows where the row IS the unit, not a card ... reads as a\n        menu rather than a grid of boxes\". As a 3-up grid it rendered\n        `grid-template-columns: 385.328px 385.328px 385.344px` -- byte-identical to\n        `steps` and `usecases`, which are declared `centered-stack`. Three components,\n        three declared families, one rendered shape. That is how the family test kept\n        passing while the senior-UI seat scored composition a 4: the test reads a label.\n     2. The orphan. This file's own comment warns \"3 or 6 rows sit flush; 4 or 5 leave a\n        ragged tail\", and the canonical sample ships five -- so \"Most Popular\" stranded\n        in the top-right corner, row heights 220px against 185px. Adding the two hourly\n        rates this section was missing would have made it 3+3+1, which is worse. A\n        vertical ledger has no tail at any count.\n     3. Comparison. Five prices in one column are read by running an eye down a single\n        edge; in a 3-up grid the same five sit at three x-positions across two rows of\n        unequal height. The section exists to be compared.\n\n   HOME is authority for structure, classes and tokens. It is not authority for a\n   composition this system elsewhere defines differently. Same precedent as `.hm-scrim`\n   and `stats`. *\/\n@media (min-width: 760px) {\n  .et-l--post .shoot-list {\n    grid-template-columns: 1fr;\n    gap: 0;\n  }\n  .et-l--post .shoot-row {\n    padding: 22px 24px;\n    align-items: center;\n  }\n  .et-l--post .shoot-row__meta {\n    margin-top: 6px;\n  }\n  .et-l--post .shoot-row__right {\n    grid-column: 2;\n    grid-row: 1 \/ span 2;\n    margin-top: 0;\n    justify-content: space-between;\n    width: auto;\n  }\n  .et-l--post .shoot-row__price {\n    font-size: var(--t-numeral-size);\n  }\n}\n.et-l--post .shoot-row__name {\n  font-weight: 600 !important;\n}\n.et-l--post .shoot-list br {\n  display:none;\n}\n\n.et-l--post .price-tabs {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 0;\n  border: 1px solid var(--accent);\n  margin-top: 28px;\n}\n.et-l--post .price-tab {\n  appearance: none;\n  background: none;\n  border: 0;\n  cursor: pointer;\n  padding: 15px 10px;\n  min-height: 56px;\n  color: var(--ink);\n  font-family: var(--font-body);\n  font-size: var(--t-ui-size);\n  font-weight: 600;\n  letter-spacing: 0.1em;\n  text-transform: uppercase;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 3px;\n  line-height: 1.2;\n  transition: background .3s, color .3s;\n}\n.et-l--post .price-tab small {\n  font-size: var(--t-micro-size);\n  font-weight: 500;\n  letter-spacing: 0.04em;\n  text-transform: none;\n  opacity: 0.62;\n}\n.et-l--post .price-tab:first-child {\n  border-right: 1px solid var(--accent);\n}\n.et-l--post .price-tab[aria-selected=\"true\"] {\n  background: var(--ivory-deep);\n  color: var(--ink);\n  box-shadow: inset 0 -2px 0 var(--ink);\n}\n.et-l--post .price-tab[aria-selected=\"true\"] small {\n  opacity: 0.75;\n}\n.et-l--post .price-panel {\n  display: none;\n  padding-top: 28px;\n}\n.et-l--post .price-panel[data-active] {\n  display: block;\n}\n.et-l--post .price-panel[hidden] {\n  display: none !important;\n}\n.et-l--post .rent-head {\n  display: flex;\n  align-items: baseline;\n  justify-content: space-between;\n  gap: 12px;\n  flex-wrap: wrap;\n}\n.et-l--post .rent-head h3 {\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: var(--t-h3-size);\n  line-height: var(--t-h3-lh);\n}\n.et-l--post .rent-head__from {\n  font-family: var(--font-body);\n  font-size: var(--t-ui-size);\n  font-weight: 600;\n  letter-spacing: 0.1em;\n  text-transform: uppercase;\n  color: var(--accent);\n}\n.et-l--post .rent-note {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--graphite);\n  margin: 6px 0 0;\n  line-height: 1.55;\n}\n.et-l--post .rent-note a {\n  color: var(--ink);\n  border-bottom: 1px solid var(--accent);\n}\n.et-l--post .rate-tiles {\n  display: grid;\n  grid-template-columns: repeat(2,1fr);\n  gap: 10px;\n  margin-top: 20px;\n}\n.et-l--post .rate-tile {\n  border: 1px solid var(--line);\n  background: var(--warm-white);\n  padding: 40px 16px 18px;\n  position: relative;\n}\n.et-l--post a.rate-tile {\n  text-decoration: none;\n  color: inherit;\n  cursor: pointer;\n  transition: border-color .2s, transform .2s;\n}\n.et-l--post a.rate-tile:hover {\n  border-color: var(--accent);\n  transform: translateY(-1px);\n}\n.et-l--post .rate-tile--feat {\n  border-color: var(--accent);\n  border-width: 1.5px;\n}\n.et-l--post .rate-tile__h {\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 600;\n  letter-spacing: 0.12em;\n  text-transform: uppercase;\n  color: var(--graphite);\n}\n.et-l--post .rate-tile__p {\n  font-family: var(--font-body);\n  font-weight: 600;\n  letter-spacing: -0.015em;\n  font-size: var(--t-numeral-size);\n  line-height: 1;\n  margin-top: 8px;\n  color: #000000;\n}\n.et-l--post .rate-tile__we {\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 500;\n  color: var(--graphite);\n  margin-top: 5px;\n}\n.et-l--post .rate-tile__flag {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 600;\n  letter-spacing: 0.1em;\n  text-transform: uppercase;\n  color: var(--ink);\n  background: var(--ivory-deep);\n  border: 1px solid var(--line);\n  padding: 4px 6px;\n  line-height: 1.2;\n}\n.et-l--post .rent-foot {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 12px 18px;\n  align-items: center;\n  justify-content: space-between;\n  margin-top: 20px;\n}\n.et-l--post .rent-foot__note {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--graphite);\n}\n.et-l--post .rent-foot__note strong {\n  color: var(--ink);\n  font-weight: 600;\n}\n@media (min-width: 760px) {\n  .et-l--post .rate-tiles {\n    grid-template-columns: repeat(4,minmax(0,1fr));\n  }\n}\n\n\/* The Rates page needs both day categories on the same duration row. These\n   semantic table cells reuse the ledger's type, spacing and hairline; the\n   existing single-amount package rows above are unchanged. *\/\n.et-l--post .shoot-list [data-price-comparison] table {\n  width: 100%;\n  border-collapse: collapse;\n  table-layout: fixed;\n  color: var(--ink);\n  font-family: var(--font-body);\n  background: transparent;\n}\n.et-l--post .shoot-list [data-price-comparison] caption,\n.et-l--post .shoot-list > [data-price-group] > h3 {\n  margin: 0 0 16px;\n  padding: 0;\n  font-family: var(--font-display);\n  font-size: var(--t-h3-size);\n  font-weight: 600;\n  line-height: var(--t-h3-lh);\n  text-align: left;\n  color: var(--ink);\n}\n.et-l--post .shoot-list [data-price-comparison] th,\n.et-l--post .shoot-list [data-price-comparison] td {\n  padding: 16px 8px;\n  border: 0;\n  border-bottom: 1px solid var(--line);\n  text-align: right;\n  font-size: var(--t-lead-size);\n  font-weight: 500;\n  line-height: 1.4;\n  font-variant-numeric: tabular-nums;\n}\n.et-l--post .shoot-list [data-price-comparison] th:first-child {\n  text-align: left;\n  padding-left: 0;\n}\n.et-l--post .shoot-list [data-price-comparison] tr > :last-child {\n  padding-right: 0;\n}\n.et-l--post .shoot-list [data-price-comparison] thead th {\n  font-size: var(--t-meta-size);\n  font-weight: 600;\n}\n.et-l--post .shoot-list [data-price-comparison] > p,\n.et-l--post .shoot-list > [data-price-group] > p {\n  font-family: var(--font-body);\n  font-size: var(--t-lead-size);\n  line-height: 1.6;\n  color: var(--graphite);\n  margin: 16px 0;\n}\n.et-l--post .shoot-list > [data-price-group] {\n  margin-top: var(--s-8);\n}\n\n\/* The HOME picker occupies the full component width. *\/\n.et-l--post .shoot-list:has(> .price-tabs) {\n  display: block;\n}\n.et-l--post .price-tabs:not([data-cc-price-ready]) {\n  display: none;\n}\n.et-l--post .bk-section:not(:has(.price-tabs[data-cc-price-ready])) .price-panel {\n  display: block;\n}\n.et-l--post .price-panel .shoot-list {\n  grid-template-columns: 1fr;\n}\n.et-l--post .price-panel .shoot-row {\n  grid-template-columns: minmax(0, 1fr) auto;\n}\n.et-l--post .price-panel .shoot-row__right {\n  grid-column: 2;\n  grid-row: 1 \/ span 2;\n  margin-top: 0;\n}\n\/* Contextual two-package lists keep their existing explanatory opening. *\/\n.et-l--post [data-price-measure=\"compact\"] .bk-h2:empty { display: none; }\n.et-l--post [data-price-measure=\"compact\"] .bk-lead { text-align: left; margin-left: 0; }\n.et-l--post [data-price-measure=\"compact\"] .pk-note { text-align: left; font-size: var(--t-meta-size); line-height: 1.55; }\n.et-l--post [data-price-measure=\"compact\"] .shoot-row { grid-template-columns: minmax(0, 1fr) auto; }\n.et-l--post [data-price-measure=\"compact\"] .shoot-row__right { grid-column: 2; grid-row: 1 \/ span 2; margin-top: 0; }\n\n\/* prose.css \u2014 the long-form body band.\n   \u26a0 Ruling C2 addition; see the SYSTEM.md additions table. Read with suspicion.\n\n   REBUILT 2026-09-14 after the owner rejected v1: \"what a private studio actually\n   charges section? like what is this? boring, text heavy and even poorly designed and\n   formatted.\" Correct on all three counts, and the cause was measurable rather than\n   a matter of taste.\n\n   v1 set body copy at .bk-lead's values \u2014 15px \/ 1.6 \/ --graphite. That is a LEAD\n   measure, meant for one introductory sentence, and it was being asked to carry whole\n   articles. Measured on the live editorial pages, the site's real body copy is:\n\n       .bp-body p        18px \/ line-height 1.75 \/ #1c1a17\n       .bp-body          max-width 752px, centred, clamp(38px, 5vw, 64px) top padding\n       .bp-body .bp-lead 'Bodoni Moda' clamp(21px, 2.6vw, 27px) \/ 1.4 \/ weight 500\n       .bp-body h3       'Bodoni Moda' 600 clamp(20px, 2.6vw, 25px), margin 1.5em 0 .4em\n       .bp-body img      width 100%, margin 1.6em 0\n\n   Three points of difference from v1, all of them the reason it read as a wall:\n     1. 18px at 1.75, not 15px at 1.6. Three points of size and 0.15 of leading is the\n        difference between an article and a caption.\n     2. A SERIF LEAD paragraph. The live pages open long-form with Bodoni at ~27px; v1\n        opened with the same 15px grey as everything else, so nothing announced a start.\n     3. INLINE IMAGERY. One live guide section carries 14 .bp-postimg images. v1 had a\n        figure slot of exactly zero. PRODUCT.md design principle 2 is \"Let the space\n        sell\" \u2014 a prose band with no photograph is the one place that principle was\n        ignored completely.\n\n   THREE THINGS DELIBERATELY NOT LIFTED, because the live editorial CSS violates this\n   project's own anti-references while getting the type right:\n     * `blockquote { border-left: 3px solid var(--taupe) }` \u2014 a side-stripe border, an\n       absolute ban. Replaced below with an indent and the serif face, which is how the\n       quote earns emphasis without a coloured rule.\n     * `border-radius: 8px` on images and tables \u2014 the rounded-card treatment the owner\n       reacted to on the bp- twins. Squared to 0, matching --btn-radius.\n     * `--taupe` on link borders and ::marker \u2014 clay is hover\/active only (One Accent\n       Rule). Links take --ink; the marker takes the body colour.\n\n   ONE TOKEN DECISION, recorded: the live body colour is #1c1a17 and the system token\n   --ink is #141210. Rather than admit a FOURTH near-black (the system already carries\n   #000000, #0B0A09 and #141210), this uses var(--ink). The visible difference is under\n   one perceptual step; a fourth black is a permanent maintenance cost.\n\n   2026-09-15 refinement: the historical serif-lead choice above is superseded.\n   Explanatory introductions use the shared Montserrat lead role; Bodoni remains\n   for headings and pull quotes. The reading column shares its heading's left axis. *\/\n\n.et-l--post .bk-prose {\n  max-width: 752px;\n  margin: 0;\n  padding: clamp(20px, 3vw, 30px) 0 0;\n}\n\n\/* Full-bleed variant, for a band carrying a table or a wide figure. *\/\n.et-l--post .bk-prose--wide {\n  max-width: none;\n}\n\n\/* The explanatory lead uses the shared lead role.\n\n   Written `p.bk-prose__lead`, not `.bk-prose__lead`, ON PURPOSE. The body rule below\n   is `.et-l--post .bk-prose p` \u2014 specificity (0,2,1) \u2014 and a bare class on the lead is\n   (0,2,0), so the body rule WINS and the lead silently renders as ordinary body copy.\n   That is exactly what shipped in the first render of this rebuild: the serif lead was\n   in the markup, in the stylesheet, and invisible. A class that loses to its own\n   component's element selector is not a style, it is a comment. *\/\n.et-l--post .bk-prose p.bk-prose__lead {\n  font-family: var(--font-body);\n  font-size: var(--t-lead-size);\n  line-height: var(--t-lead-lh);\n  font-weight: 500;\n  color: var(--ink);\n  margin: 0 0 1em;\n  text-wrap: pretty;\n}\n\n.et-l--post .bk-prose p,\n.et-l--post .bk-prose li {\n  font-family: var(--font-body);\n  font-size: 18px;\n  font-weight: 400;\n  line-height: 1.75;\n  color: var(--ink);\n}\n\n.et-l--post .bk-prose p {\n  margin: 0 0 1.25em;\n  text-wrap: pretty;\n}\n\n.et-l--post .bk-prose p:last-child {\n  margin-bottom: 0;\n}\n\n.et-l--post .bk-prose h3 {\n  font-family: var(--font-display);\n  font-weight: 600;\n  font-size: clamp(20px, 2.6vw, 25px);\n  line-height: 1.2;\n  letter-spacing: -0.01em;\n  color: var(--ink);\n  margin: 1.5em 0 0.4em;\n  text-wrap: balance;\n}\n\n.et-l--post .bk-prose h3:first-child {\n  margin-top: 0;\n}\n\n.et-l--post .bk-prose ul {\n  margin: 0 0 1.3em;\n  padding-left: 1.25em;\n  list-style: disc;\n}\n\n.et-l--post .bk-prose li {\n  margin: 0 0 0.55em;\n}\n\n.et-l--post .bk-prose strong,\n.et-l--post .bk-prose b {\n  color: var(--ink);\n  font-weight: 700;\n}\n\n.et-l--post .bk-prose a {\n  color: var(--ink);\n  text-decoration: none;\n  border-bottom: 1.5px solid var(--ink);\n  padding-bottom: 1px;\n}\n\n.et-l--post .bk-prose a:hover {\n  border-bottom-color: var(--accent);\n}\n\n\/* Inline imagery. The thing v1 was missing entirely. Square, full measure, and it\n   breaks the column rather than sitting beside it \u2014 the live pages do the same. *\/\n.et-l--post .bk-prose figure {\n  margin: 1.6em 0;\n}\n\n.et-l--post .bk-prose img {\n  width: 100%;\n  height: auto;\n  display: block;\n  border-radius: 0;\n}\n\n.et-l--post .bk-prose figcaption {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--graphite);\n  margin-top: 8px;\n}\n\n\/* The pull quote, WITHOUT the side stripe. Emphasis comes from the display face and\n   the indent, which is what the rest of this system uses for emphasis anywhere else. *\/\n.et-l--post .bk-prose blockquote {\n  margin: 1.7em 0;\n  padding: 0 0 0 1.3em;\n  font-family: var(--font-display);\n  font-size: clamp(20px, 2.4vw, 23px);\n  line-height: 1.35;\n  font-style: italic;\n  color: var(--ink);\n}\n\n\/* 14 of the 73 measured prose sections carry no heading at all. Rendering an empty\n   <h2> would ship an axe \"empty-heading\" violation and a phantom line-box. *\/\n.et-l--post [data-screen-label=\"prose\"] .bk-h2:empty {\n  display: none;\n}\n\n\/* reviews.css -- HOME-like Google review card carousel.\n   Current HOME renders Trustindex review cards: white cards on the section ground,\n   a compact name\/source header, gold stars, a Google mark, and horizontal controls.\n   The cc_system component keeps the existing typed review figures and restores that\n   composition without embedding a third-party widget or fabricating review content. *\/\n\n\/* Josefin targets #reviews h2 with an important mobile size intended for its\n   product-review widget. HOME's review heading keeps the shared section scale. *\/\n.et-l--post #reviews .bk-h2 {\n  font-size: clamp(28px, 6vw, 46px) !important;\n}\n\n.et-l--post .rev-grid {\n  position: relative;\n  margin-top: clamp(22px, 3vw, 30px);\n}\n\n.et-l--post .rev-grid > [role=\"list\"] {\n  display: grid;\n  grid-auto-flow: column;\n  grid-auto-columns: minmax(310px, 1fr);\n  gap: 18px;\n  overflow-x: auto;\n  scroll-snap-type: x mandatory;\n  scroll-behavior: smooth;\n  padding: 0 0 26px;\n  scrollbar-width: thin;\n  scrollbar-color: rgba(20, 18, 16, 0.28) rgba(20, 18, 16, 0.14);\n}\n\n.et-l--post .rev-grid > [role=\"list\"]::-webkit-scrollbar {\n  height: 4px;\n}\n\n.et-l--post .rev-grid > [role=\"list\"]::-webkit-scrollbar-track {\n  background: rgba(20, 18, 16, 0.14);\n}\n\n.et-l--post .rev-grid > [role=\"list\"]::-webkit-scrollbar-thumb {\n  background: rgba(20, 18, 16, 0.36);\n}\n\n@media (min-width: 920px) {\n  .et-l--post .rev-grid > [role=\"list\"] {\n    grid-auto-columns: calc((100% - 36px) \/ 2.5);\n  }\n}\n\n.et-l--post .rev {\n  position: relative;\n  scroll-snap-align: start;\n  min-height: 232px;\n  margin: 0;\n  padding: 24px 22px 22px;\n  border: 1px solid rgba(20, 18, 16, 0.14);\n  background: #fff;\n  box-shadow: 0 10px 18px rgba(20, 18, 16, 0.08);\n  display: flex;\n  flex-direction: column;\n}\n\n.et-l--post .rev::before {\n  content: \"\";\n  position: absolute;\n  top: 24px;\n  right: 22px;\n  width: 20px;\n  height: 20px;\n  background: url(\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\") center \/ contain no-repeat;\n}\n\n.et-l--post .rev blockquote,\n.et-l--post [data-screen-label=\"reviews\"] .rev blockquote {\n  order: 2;\n  margin: 0;\n  padding: 0 34px 0 0;\n  border: 0;\n  font-family: var(--font-body);\n  font-size: 15px;\n  font-weight: 400;\n  line-height: 1.5;\n  color: var(--graphite);\n}\n\n.et-l--post #reviews .rev blockquote {\n  font-family: var(--font-body);\n  font-size: 15px;\n  font-weight: 400;\n  line-height: 1.5;\n  color: var(--graphite);\n}\n\n.et-l--post .rev blockquote::before,\n.et-l--post #reviews .rev blockquote::before {\n  content: \"\u2605\u2605\u2605\u2605\u2605\";\n  display: block;\n  margin: 9px 0 9px;\n  color: #f5ad00;\n  font-size: clamp(20px, 2.6vw, 25px);\n  line-height: 1;\n  letter-spacing: 1px;\n}\n\n.et-l--post .rev blockquote::after {\n  content: \"\u201c\";\n  position: absolute;\n  right: 22px;\n  bottom: 14px;\n  font-family: Georgia, serif;\n  font-size: clamp(34px, 9vw, 60px);\n  line-height: 0.8;\n  color: rgba(20, 18, 16, 0.48);\n}\n\n.et-l--post .rev figcaption,\n.et-l--post [data-screen-label=\"reviews\"] .rev figcaption {\n  order: 1;\n  padding-right: 44px;\n  font-family: var(--font-body);\n  font-size: 14px;\n  font-weight: 800;\n  line-height: 1.16;\n  letter-spacing: 0.08em;\n  color: var(--ink);\n  text-transform: none;\n}\n\n.et-l--post .rev figcaption span {\n  display: block;\n  margin-top: 4px;\n  font-size: 10px;\n  font-weight: 700;\n  letter-spacing: 0.16em;\n  text-transform: uppercase;\n  color: var(--graphite);\n}\n\n\n.et-l--post [data-screen-label=\"reviews\"] .rev blockquote[data-review-collapsed=\"true\"] {\n  max-height: 128px;\n  overflow: hidden;\n}\n\n.et-l--post [data-screen-label=\"reviews\"] .rev blockquote[data-review-collapsed=\"false\"] {\n  max-height: none;\n  overflow: visible;\n}\n\n.et-l--post .rev [data-review-toggle] {\n  order: 3;\n  align-self: flex-start;\n  min-width: 44px;\n  min-height: 44px;\n  margin: 6px 0 0;\n  padding: 0 0 2px;\n  border: 0;\n  border-bottom: 1px solid currentColor;\n  display: inline-flex;\n  align-items: center;\n  background: transparent;\n  color: var(--ink);\n  font-family: var(--font-body);\n  font-size: 15px;\n  font-weight: 800;\n  letter-spacing: 0.12em;\n  line-height: 1.2;\n  text-transform: uppercase;\n  cursor: pointer;\n  touch-action: manipulation;\n}\n\n.et-l--post .rev [data-review-toggle]:focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 3px;\n}\n\n.et-l--post .rev-grid > button {\n  position: absolute;\n  top: 50%;\n  z-index: 2;\n  width: 44px;\n  height: 44px;\n  padding: 0;\n  border: 1px solid rgba(20, 18, 16, 0.28);\n  border-radius: 50%;\n  display: none;\n  background: #fff;\n  color: var(--ink);\n  font: 400 clamp(20px, 2.6vw, 25px)\/40px Georgia, serif;\n  cursor: pointer;\n  transform: translateY(-50%);\n}\n\n.et-l--post .rev-grid[data-reviews-overflow] > button {\n  display: block;\n}\n\n.et-l--post .rev-grid > button:first-of-type {\n  left: -22px;\n}\n\n.et-l--post .rev-grid > button:last-of-type {\n  right: -22px;\n}\n\n.et-l--post .rev-grid > button:disabled {\n  opacity: 0.35;\n  cursor: default;\n}\n\n.et-l--post .rev-grid > button:focus-visible,\n.et-l--post .rev-grid > [role=\"list\"]:focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 3px;\n}\n\n\n.et-l--post .rev-grid + p {\n  margin: clamp(8px, 1.5vw, 14px) 0 0;\n  font-family: var(--font-body);\n  font-size: 15px;\n  font-weight: 700;\n  letter-spacing: 0.14em;\n  text-transform: uppercase;\n}\n\n.et-l--post .rev-grid + p a {\n  border-bottom: 1px solid currentColor;\n}\n\n.et-l--post .rev-grid + p a:focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 3px;\n}\n\n@media (max-width: 700px) {\n  .et-l--post .rev-grid > [role=\"list\"] {\n    grid-auto-columns: 100%;\n  }\n\n}\n\n.et-l--post [data-screen-label=\"reviews\"] .container-bk > p:empty { display: none; }\n.et-l--post [data-screen-label=\"reviews\"] .rev-grid[hidden] { display: none !important; }\n.et-l--post [data-screen-label=\"reviews\"] .cc-live-feed--reviews { margin-top: 18px; }\n\n\/* Trustindex emits the populated widget with an inline loading state. On cached\n   WordPress renders its initializer can fail to remove that state, leaving real\n   review cards in the DOM at opacity:0 and height:0. The plugin stylesheet already\n   owns the carousel layout; this only restores the visible state of populated markup. *\/\n.et-l--post .cc-live-feed--reviews .ti-widget[data-trustindex-widget].cc-live-feed--ready {\n  opacity: 1 !important;\n  height: auto !important;\n  overflow: visible !important;\n}\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post .rev-grid > [role=\"list\"] { scroll-behavior: auto; }\n}\n\n\/* Keep both carousel controls inside the viewport, clear of review text. *\/\n.et-l--post .rev-grid { padding-bottom: 56px; }\n.et-l--post .rev-grid > button { top: auto; bottom: 0; transform: none; }\n.et-l--post .rev-grid > button:first-of-type { left: auto; right: 54px; }\n.et-l--post .rev-grid > button:last-of-type { right: 0; }\n@media (max-width: 359px) {\n  .et-l--post .rev-grid > [role=\"list\"] { grid-auto-columns: 90%; }\n}\n\n\/* The section's edges are derived (`proof` role, spacing.py). Trustindex ends its\n   widget with `.ti-controls-line { margin-bottom: 20px }` inside a container with\n   `margin-bottom: 15px`; both collapse out of the widget and added 20px of blank space\n   under every review carousel (measured 2026-09-24). The widget's last row now ends\n   on the section's content edge. *\/\n.et-l--post .cc-live-feed--reviews .ti-widget-container,\n.et-l--post .cc-live-feed--reviews .ti-controls-line { margin-bottom: 0 !important; }\n\n\/* room.css \u2014 a single-room feature card with an embedded tour-video facade\n   in place of a photo, extracted from reference\/home.css. Every selector\n   scoped to .et-l--post per the project's CSS-specificity rule.\n\n   Composition note: HOME's own live page uses .cc-tourvid standalone (no\n   .space-feat wrapper) for its studio-tour section (offset ~52192,\n   <section class=\"bk-section bk-section--tight\" id=\"space\">...<div\n   class=\"cc-tourvid\">...<\/div>). .space-feat (offset ~85394) is HOME's own\n   media+body feature-card layout, used elsewhere for a room\/amenity card\n   with a photo in .space-feat__media. This component combines the two real\n   HOME class families deliberately: .space-feat \/ .space-feat--solo for the\n   card shell (media column + text column, single-card variant), with\n   .cc-tourvid's video facade dropped into the .space-feat__media slot\n   instead of a photo. No class is invented; both families already ship on\n   HOME. *\/\n\n\/* .space-feat \/ .space-feat--solo \u2014 the card shell. Two declarations for\n   .space-feat: mobile-default single column (offset ~85394) and a desktop\n   2-column split (offset ~106656, inside @media (min-width:760px)) \u2014 both\n   transcribed, additive by breakpoint, no conflict. .space-feat--solo has\n   exactly one declaration (offset ~85351, inside @media (max-width:600px),\n   !important) \u2014 it only forces 1fr on narrow viewports; at desktop width\n   the plain .space-feat 2-column media+text split still applies since\n   --solo carries no desktop override of its own. *\/\n.et-l--post .space-feat {\n  display: grid;\n  grid-template-columns: 1fr;\n  gap: 18px;\n  margin-top: 28px;\n}\n\n\/* .space-feat__media \u2014 the media column. Two declarations: base aspect-\n   ratio 4\/3 (offset ~85394) and a desktop aspect-ratio:auto (offset\n   ~106656) that lets the video facade's own 16\/9 ratio govern instead. *\/\n\/* 16\/9 at every width, 2026-09-14. HOME ships 4\/3 with a desktop `auto`; that is two\n   ratios in a slot `direction.json` declares as one (\"room_poster\": \"16:9\"), and it\n   rendered 1.333 at 390 and a content-sized 1.645 at 1440 -- the declared ratio at\n   neither. The `auto` existed so the video facade's own 16\/9 could govern, which is\n   an argument for 16\/9 being the slot's real ratio rather than for leaving it\n   unstated. Recorded Divergence from HOME, same basis as `.hm-scrim` and `price`. *\/\n.et-l--post .space-feat__media {\n  position: relative;\n  overflow: visible;\n}\n\/* .space-feat__media img \/ :hover img \u2014 HOME's own declarations for a\n   photo in this slot. Kept verbatim even though this component fills the\n   slot with .cc-tourvid instead of an <img>, so the class still behaves\n   correctly if a page ever swaps in a plain photo here. *\/\n.et-l--post .space-feat__media img {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  transition: transform 1s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .space-feat__media:hover img {\n  transform: scale(1.04);\n}\n\n\/* .space-feat__body \u2014 the text column. One declaration each for the\n   container, its h3 and its p (offset ~85394). This component uses the\n   h2 and body placeholders as plain text inside a bare p, so only the container and\n   p rules are load-bearing; h3 is kept for parity with HOME's own shape\n   in case a future page author nests a heading here too. *\/\n.et-l--post .space-feat__body {\n  padding: clamp(24px, 5vw, 34px);\n  background: var(--warm-white);\n  border: 1px solid var(--line);\n}\n\/* Supporting copy is optional. When the heading and video already explain the\n   section, an empty slot must not render as a blank bordered panel. *\/\n.et-l--post .space-feat__body:empty {\n  display: none;\n}\n.et-l--post .space-feat__body h3 {\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: clamp(24px,4.6vw,34px);\n  line-height: 1.05;\n  margin: 0 0 12px;\n  font-weight: 600;\n}\n.et-l--post .space-feat__body p {\n  font-size: var(--t-body-size);\n  margin: 0 0 16px;\n  text-wrap: pretty;\n  font-weight: 500;\n  color: var(--graphite);\n  line-height: 1.6;\n}\n.et-l--post .space-feat__body ul,\n.et-l--post .space-feat__body .amen {\n  display: grid;\n  grid-template-columns: repeat(2, minmax(0, 1fr));\n  gap: 11px 24px;\n  list-style: none;\n  padding: 20px 0 0;\n  margin: 18px 0 0;\n  border-top: 1px solid var(--line);\n}\n.et-l--post .space-feat__body li {\n  position: relative;\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  line-height: 1.4;\n  color: var(--ink);\n  padding: 0 0 0 22px;\n}\n.et-l--post .space-feat__body li::before {\n  content: \"\u2713\";\n  position: absolute;\n  left: 0;\n  top: 0;\n}\n.et-l--post .space-feat__media .cc-tourvid { margin-top: 0; }\n.et-l--post .space-feat__body [data-cc-video-link] {\n  margin-top: 16px;\n  font-size: var(--t-meta-size);\n}\n.et-l--post .space-feat__body [data-cc-video-link] {\n  color: var(--ink);\n  border-bottom: 1px solid var(--accent);\n}\n\n\/* .cc-tourvid \u2014 the video facade wrapper. HOME ships THREE declarations\n   for this exact bare selector (confirmed by enumerating every literal\n   \".cc-tourvid\" occurrence in reference\/home.css, not just the first\n   match): a mobile-default full-bleed breakout (offset ~55643, unscoped\n   in the source \u2014 .et-l--post prefix added here per the project rule),\n   a desktop cap to 760px inside @media (min-width:760px) (offset ~55688,\n   also unscoped in the source), and an additive margin-top (offset\n   ~85372, already scoped in the source). No !important on any of the\n   three, and the two base\/media declarations touch disjoint breakpoints\n   (mobile default vs. min-width:760px) so there is no real conflict to\n   resolve \u2014 all three combine. Full-bleed-mobile \/ capped-desktop is a\n   deliberate, documented HOME pattern (project memory:\n   \"full-bleed MOBILE-ONLY, desktop capped 760px\"). *\/\n.et-l--post .cc-tourvid {\n  position: relative;\n  left: 50%;\n  right: 50%;\n  width: 100vw;\n  max-width: 100vw;\n  margin-left: -50vw;\n  margin-right: -50vw;\n  overflow: hidden;\n  background: var(--black);\n  line-height: 0;\n  margin-top: 28px;\n}\n@media (min-width: 760px) {\n  .et-l--post .cc-tourvid {\n    position: relative;\n    left: auto;\n    right: auto;\n    width: 100%;\n    max-width: 760px;\n    margin-left: 0;\n    margin-right: auto;\n  }\n}\n\n\/* .cc-yt-facade \/ .cc-yt-play \u2014 the click-to-play thumbnail and its play\n   glyph, always scoped as descendants of .cc-tourvid, one declaration each\n   (offset ~55655-56941). Unscoped in the source (bare \".cc-tourvid\n   .cc-yt-facade\", etc.) \u2014 .et-l--post prefix added per the project rule. *\/\n.et-l--post .cc-tourvid .cc-yt-facade {\n  position: relative;\n  display: block;\n  width: 100%;\n  aspect-ratio: 16\/9;\n  background: var(--black);\n  border: 0;\n  cursor: pointer;\n  overflow: hidden;\n}\n.et-l--post .cc-tourvid .cc-yt-facade img {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  display: block;\n  border: 0;\n  margin: 0;\n}\n.et-l--post .cc-tourvid .cc-yt-facade iframe {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n  display: block;\n}\n.et-l--post .cc-tourvid .cc-yt-play {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 74px;\n  height: 52px;\n  background: rgba(0,0,0,.72);\n  pointer-events: none;\n  transition: background .25s cubic-bezier(.22,1,.36,1);\n}\n.et-l--post .cc-tourvid .cc-yt-play::after {\n  content: \"\";\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-40%, -50%);\n  border: solid transparent;\n  border-width: 11px 0 11px 19px;\n  border-left-color: #fff;\n}\n.et-l--post .cc-tourvid .cc-yt-facade:hover .cc-yt-play,\n.et-l--post .cc-tourvid .cc-yt-facade:focus-visible .cc-yt-play {\n  background: #8D8175;\n}\n.et-l--post .cc-tourvid .cc-yt-facade:focus-visible {\n  outline: 2px solid #8D8175;\n  outline-offset: -4px;\n}\n\n.et-l--post .space-feat .cc-yt-facade {\n  padding: 0;\n}\n.et-l--post .space-feat div.cc-yt-facade {\n  cursor: default;\n}\n\n.et-l--post .cc-tourvid button.cc-yt-facade { padding: 0; border: 0; cursor: pointer; }\n\n\/* Walkthrough variant: one full-width video after the introduction owns the specs. *\/\n.et-l--post [data-room-layout=\"walkthrough\"] .space-feat { grid-template-columns: 1fr; gap: 24px; margin-top: 20px; }\n.et-l--post [data-room-layout=\"walkthrough\"] .space-feat__body { order: -1; padding: 0; border: 0; background: transparent; max-width: 70ch; }\n.et-l--post [data-room-layout=\"walkthrough\"] .space-feat__body p { margin: 0; }\n.et-l--post [data-room-layout=\"walkthrough\"] .cc-tourvid { margin-top: 0; max-width: none; }\n\n\/* specacc.css \u2014 HOME's specs\/amenities accordion (.specacc), extracted\n   verbatim from reference\/home.css (offset ~98712-100200, one contiguous\n   block). Every selector scoped to .et-l--post per the project's\n   CSS-specificity rule. Exactly one declaration found for each selector\n   below (enumerated every literal occurrence in reference\/home.css, not\n   just the first match) \u2014 no cascade conflicts, except .specacc__list's\n   own column count, which is additive by breakpoint (see below).\n\n   Fix round 1: .specacc__body ships max-height:0 with no companion CSS\n   rule that expands it for [aria-expanded=\"true\"] because the expand\n   happens in JS, not CSS \u2014 confirmed inline in scratchpad\/home.html\n   (comment \"spec accordion (Amenities & Equipment)\"), the same file\n   already mined for .cc-tourvid\/.gal-tabs. specacc.html now carries that\n   exact script (click toggle, initial-state pass, resize handler),\n   brace-doubled for str.format() the same way room.html\/gallery.html\n   are. *\/\n.et-l--post .specacc {\n  border-top: 1px solid var(--line);\n  margin-top: 28px;\n}\n.et-l--post .specacc__item {\n  border-bottom: 1px solid var(--line);\n}\n.et-l--post .specacc__head {\n  width: 100%;\n  background: none;\n  border: 0;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 16px;\n  padding: 22px 2px;\n  text-align: left;\n  color: inherit;\n}\n.et-l--post .specacc__head h3 {\n  margin: 0;\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: clamp(20px, 4.6vw, 27px);\n  line-height: 1.08;\n}\n.et-l--post .specacc__head .meta {\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 600;\n  letter-spacing: 0.12em;\n  text-transform: uppercase;\n  color: var(--graphite);\n  margin-top: 5px;\n}\n.et-l--post .specacc__icon {\n  position: relative;\n  width: 17px;\n  height: 17px;\n  flex: 0 0 auto;\n}\n.et-l--post .specacc__icon::before,\n.et-l--post .specacc__icon::after {\n  content: \"\";\n  position: absolute;\n  background: var(--accent);\n  transition: transform .35s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .specacc__icon::before {\n  top: 50%;\n  left: 0;\n  right: 0;\n  height: 1.5px;\n  transform: translateY(-50%);\n}\n.et-l--post .specacc__icon::after {\n  left: 50%;\n  top: 0;\n  bottom: 0;\n  width: 1.5px;\n  transform: translateX(-50%);\n}\n\/* FIX 5: aria-expanded lives on .specacc__head (the button that is actually\n   focused and clicked), not on the wrapping .specacc__item div \u2014 see\n   specacc.html's script. *\/\n.et-l--post .specacc__head[aria-expanded=\"true\"] .specacc__icon::after {\n  transform: translateX(-50%) scaleY(0);\n}\n.et-l--post .specacc__body {\n  overflow: hidden;\n  max-height: none;\n  transition: max-height .45s cubic-bezier(.4,0,.2,1);\n}\n\/* .specacc__list \u2014 mobile-default 1 column; desktop widens to 2 (offset\n   ~106656, inside @media (min-width:760px)), plus a desktop-only border\n   restored on the 2nd item once it moves into its own row \u2014 additive by\n   breakpoint, not a conflict. *\/\n.et-l--post .specacc__list {\n  list-style: none;\n  margin: 0;\n  padding: 2px 2px 24px;\n  display: grid;\n  grid-template-columns: 1fr;\n  gap: 0;\n}\n@media (min-width: 760px) {\n  .et-l--post .specacc__list {\n    grid-template-columns: 1fr 1fr;\n    gap: 0 32px;\n  }\n  .et-l--post .specacc__list li:nth-child(2) {\n    border-top: 1px solid var(--line);\n  }\n}\n.et-l--post .specacc__list li {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  line-height: 1.4;\n  color: var(--ink);\n  padding: 10px 0;\n  border-top: 1px solid var(--line);\n  display: flex;\n  gap: 11px;\n  align-items: flex-start;\n}\n.et-l--post .specacc__list li:first-child,\n.et-l--post .specacc__list li:nth-child(2) {\n  border-top: 0;\n}\n.et-l--post .specacc__list li svg {\n  width: 14px;\n  height: 14px;\n  color: var(--accent);\n  flex: 0 0 auto;\n  margin-top: 3px;\n}\n\n\/* Section edges are derived (`content` role, spacing.py) like every other section;\n   the compact 36px \/ 24px override was retired with the spacing conditions, 2026-09-24. *\/\n\n\/* HOME's value grid, restored by owner direction on 2026-09-16.\n   Lift: tools\/cc_system\/lift.py --classes stats stat stat__n stat__l.\n   Duplicate winners: desktop .stats uses four columns; .stat__n uses weight 600.\n   Same-day production at 390\/1440 confirms the warm-white cells and Bodoni figures.\n   The label uses the existing 11px micro role: a 0.5px readability refinement.\n   Label line-height is captured explicitly from HOME's inherited Divi values so\n   the canonical body scale does not change the card heights. *\/\n\n.et-l--post [data-screen-label=\"stats\"] .intro-wrap {\n  text-align: left;\n  max-width: none;\n  margin: 0;\n}\n\n.et-l--post [data-screen-label=\"stats\"] .intro-wrap .bk-h2 {\n  font-size: clamp(28px,6vw,46px);\n  line-height: 1.04;\n  letter-spacing: -0.01em;\n}\n\n.et-l--post [data-screen-label=\"stats\"] .intro-wrap .bk-lead {\n  margin-left: 0;\n  margin-right: 0;\n  font-size: 16px;\n}\n\n.et-l--post .stats {\n  display: grid;\n  grid-template-columns: repeat(2,1fr);\n  gap: 1px;\n  background: var(--line);\n  border: 1px solid var(--line);\n  margin-top: 34px;\n}\n\n.et-l--post .stat {\n  background: var(--warm-white);\n  padding: 24px 14px;\n  text-align: center;\n}\n\n.et-l--post .stat__n {\n  font-family: var(--font-display);\n  font-weight: 600 !important;\n  font-size: clamp(30px,7vw,46px);\n  line-height: 1;\n  letter-spacing: -0.01em;\n  color: #000000;\n}\n\n.et-l--post .stat__l {\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 600;\n  line-height: 21.6px;\n  letter-spacing: 0.14em;\n  text-transform: uppercase;\n  color: var(--graphite);\n  margin-top: 8px;\n}\n\n@media (min-width: 760px) {\n  .et-l--post .stats {\n    grid-template-columns: repeat(4,minmax(0,1fr));\n  }\n}\n\n@media (min-width: 768px) {\n  .et-l--post .stat__l {\n    line-height: 25.2px;\n  }\n}\n\n.et-l--post .stats br {\n  display: none;\n}\n\n\/* Owner notes: left-aligned introduction; retain HOME\u2019s four value cards. *\/\n@media (min-width: 920px) {\n  .et-l--post [data-screen-label=\"stats\"] .intro-wrap {\n    display: grid;\n    grid-template-columns: 1.1fr 1fr;\n    gap: 64px;\n    align-items: end;\n  }\n  .et-l--post [data-screen-label=\"stats\"] .intro-wrap .bk-lead { margin: 0; }\n}\n\n\/* steps.css \u2014 HOME's numbered how-it-works list (.steps), extracted\n   verbatim from reference\/home.css (offset ~103950-104200). Every\n   selector scoped to .et-l--post per the project's CSS-specificity rule.\n   Exactly one declaration found for each selector below (enumerated\n   every literal occurrence in reference\/home.css, not just the first\n   match) \u2014 no cascade conflicts, except .steps's own column count,\n   which is additive by breakpoint (see below).\n\n   HOME declares `counter-reset: step` on .steps but ships no matching\n   `counter-increment` \/ `content: counter(step)` rule anywhere in\n   reference\/home.css (confirmed by search) \u2014 the reset is vestigial in\n   HOME's own CSS. This component does not rely on it; the number in\n   each .step__n is supplied as literal text by the caller, inside the\n   items slot, matching how HOME's own font-only styling of .step__n\n   (no ::before\/content rule) implies the number is markup, not\n   CSS-generated. *\/\n.et-l--post .steps {\n  display: grid;\n  grid-template-columns: 1fr;\n  gap: 12px;\n  margin-top: 28px;\n  counter-reset: step;\n}\n@media (min-width: 760px) {\n  .et-l--post .steps {\n    grid-template-columns: repeat(3, minmax(0, 1fr));\n  }\n}\n.et-l--post .step {\n  border: 1px solid var(--line);\n  background: var(--warm-white);\n  padding: 26px 22px;\n  position: relative;\n}\n\/* .step__n \u2014 FIX 3 (Task 10): HOME's own value here (a large, low-opacity\n   ghost numeral) is exactly the \"01\/02\/03 numbered section marker\" DESIGN.md\n   line 169 explicitly bans, and this owner has a documented history of\n   rejecting that scaffold on sight. Two independent reviewers flagged it on\n   this page. The h3 verbs already carry the sequence (Pick Your Option ->\n   Record Your Episode -> Get Your Files), reinforced by plain DOM\/grid\n   order, so the numeral is redundant, not informative \u2014 removed outright\n   rather than restyled into a different decorative marker (a bullet, an\n   icon, a badge would all just be the same scaffold in a new shape).\n   Content authoring is a separate pass, so the manifest's own item markup\n   still supplies a literal \"1\"\/\"2\"\/\"3\" text node here; this rule is the\n   system-level guarantee that it never renders as ghost-numeral scaffolding\n   again, on this page or any future one built from this component. *\/\n.et-l--post .step__n {\n  display: none;\n}\n.et-l--post .step h3 {\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: clamp(19px, 4vw, 23px);\n  line-height: 1.1;\n  margin: 8px 0 6px;\n}\n.et-l--post .step p {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  color: var(--graphite);\n  line-height: 1.5;\n  margin: 0;\n}\n\/* The ledger stacks on mobile; give the description its own readable line gap.\n   Target the paragraph so hierarchy.css's heading margin reset cannot erase it. *\/\n@media (max-width: 759px) {\n  .et-l--post .step h3 + p {\n    margin-top: var(--s-2);\n  }\n}\n\n\/* Shared booking bar. The zero-height sticky anchor sits at the dynamic\n   viewport edge without adding document height. Its surface rises above that\n   anchor, avoiding WebKit's faulty `position:fixed; bottom:0` path while\n   keeping the approved safe-area padding and visibility behavior. The script\n   moves the anchor directly before #page-container so Divi transforms and\n   overflow cannot become its sticky containing block. *\/\n.stickybar {\n  position: sticky;\n  top: 100vh;\n  top: 100dvh;\n  width: 100%;\n  height: 0;\n  z-index: 999999;\n  pointer-events: none;\n}\n.stickybar__surface {\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: #FCF8F0;\n  border-top: 1px solid rgba(20,18,16,.18);\n  padding: 11px clamp(16px, 4vw, 22px);\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 14px;\n  transform: translateY(120%);\n  visibility: hidden;\n  pointer-events: none;\n  transition: transform var(--motion-base) var(--motion-ease);\n  box-shadow: 0 -8px 24px rgba(11,10,9,.12);\n}\n\n\/* Browser tabs already reserve their own bottom safe area. Adding the inset\n   again creates an empty ivory band under the CTA on iPhone Safari and Chrome.\n   Installed\/fullscreen web apps do draw into that area, so only those display\n   modes receive the device inset. *\/\n@media (display-mode: standalone), (display-mode: fullscreen) {\n  .stickybar__surface {\n    padding-bottom: max(11px, env(safe-area-inset-bottom));\n  }\n}\n.stickybar.show .stickybar__surface {\n  transform: translateY(0);\n  visibility: visible;\n  pointer-events: auto;\n}\n.stickybar__price b {\n  font-family: Montserrat, sans-serif;\n  font-size: 14px;\n  font-weight: 700;\n  display: block;\n  line-height: 1.2;\n  color: #000;\n}\n\/* FIX 6 (Task 10): measured 41px tall at 390px \u2014 below the 44px minimum tap\n   target. Vertical padding raised 13px -> 15px (44 -> 45px with the 1px\n   border top+bottom already counted); horizontal padding, font-size and\n   weight are untouched so the button's visual weight doesn't change. *\/\n.stickybar .btn--bar {\n  background: #000;\n  color: #FCF8F0;\n  border: 1px solid #000;\n  border-radius: 0;\n  font-family: Montserrat, sans-serif;\n  font-weight: 600;\n  font-size: var(--t-meta-size);\n  letter-spacing: .06em;\n  text-transform: uppercase;\n  text-decoration: none;\n  padding: 12px clamp(14px, 4vw, 26px);\n  min-height: 44px;\n  min-width: min-content;\n  box-sizing: border-box;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  text-align: center;\n  white-space: normal;\n  overflow-wrap: normal;\n  line-height: 1.25;\n  transition: background .2s, border-color .2s;\n}\n.stickybar .btn--bar:hover {\n  background: #8D8175;\n  border-color: #8D8175;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .stickybar__surface, .stickybar .btn--bar {\n    transition: none;\n  }\n}\n\n\/* Phase 2 recovery: the actual provider is the opening view, without a second poster. *\/\n.et-l--post .cc-tour-section { padding-top: var(--s-5); }\n.et-l--post .cc-tour-section__lead { max-width: 62ch; }\n.et-l--post .cc-tour-section__lead:empty,\n.et-l--post .cc-tour-section .bk-h2:empty { display: none; }\n.et-l--post .cc-tour { margin-top: var(--s-5); }\n.et-l--post .cc-tour-section .bk-h2:empty + .cc-tour-section__lead:empty + .cc-tour { margin-top: 0; }\n\/* 2026-09-28: the frame sits on the section's own ground while the provider loads; ivory-deep read as a\n   tinted box (A22, 62% of the section). *\/\n.et-l--post .cc-tour__stage { position: relative; width: 100%; aspect-ratio: 16 \/ 9; min-height: 360px; max-height: 680px; background: transparent; }\n.et-l--post .cc-tour__frame,\n.et-l--post .cc-tour__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }\n.et-l--post .cc-tour__footer { display: none; }\n.et-l--post .cc-tour[data-tour-state=\"unavailable\"] .cc-tour__footer { display: flex; justify-content: flex-end; padding-top: var(--s-3); }\n.et-l--post .cc-tour__status { position: absolute; inset: 0; z-index: 1; display: grid; justify-items: center; align-content: center; gap: var(--s-4); margin: 0; padding: var(--s-6); background: transparent; color: var(--ink); font-size: var(--t-body-size); line-height: 1.6; text-align: center; }\n.et-l--post .cc-tour[data-tour-state=\"loading\"] .cc-tour__status::before { content: \"\"; display: block; width: 28px; height: 28px; border: 2px solid var(--line); border-top-color: var(--ink); border-radius: 50%; animation: cc-tour-loading 1s linear infinite; }\n.et-l--post .cc-tour[data-tour-state=\"loaded\"] .cc-tour__status { display: none; }\n@keyframes cc-tour-loading { to { transform: rotate(360deg); } }\n@media (prefers-reduced-motion: reduce) { .et-l--post .cc-tour[data-tour-state=\"loading\"] .cc-tour__status::before { animation: none; } }\n.et-l--post .cc-tour__status:empty { display: none; }\n.et-l--post .cc-tour [hidden] { display: none; }\n.et-l--post .cc-tour__start { display: none; }\n@media (max-width: 600px) {\n  .et-l--post .cc-tour__stage { width: 100vw; margin-left: calc((100% - 100vw) \/ 2); aspect-ratio: auto; height: var(--cc-tour-h, 480px); }\n  \/* Phones: one tap starts Matterport IN the page (play=1, >= 60% of the screen); its own play button leaves it. *\/\n  .et-l--post .cc-tour__start { display: block; position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; cursor: pointer; }\n  .et-l--post .cc-tour__start:focus-visible { outline: 2px solid #8D8175; outline-offset: -4px; }\n}\n\n\/* trust.css \u2014 HOME's post-hero trust bar (.bk-trust), extracted verbatim\n   from reference\/home.css (offset ~82191). Every selector scoped to\n   .et-l--post per the project's CSS-specificity rule.\n\n   F6 fix is baked in by omission: this is HOME's real, plain 3-up trust\n   row \u2014 no bordered grid box, no .ccmat__facts. Do not add either back. *\/\n.et-l--post .bk-trust {\n  background: var(--ivory-deep);\n  border-top: 1px solid var(--line);\n  border-bottom: 1px solid var(--line);\n}\n.et-l--post .bk-trust__row {\n  display: grid;\n  grid-template-columns: repeat(3, 1fr);\n  gap: 1px;\n  background: var(--line);\n}\n.et-l--post .bk-trust__item {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 6px;\n  text-align: center;\n  padding: 18px 8px;\n  background: var(--ivory-deep);\n}\n\/* Fix round 1, Important: the reviews item is an <a>, and there is no\n   sitewide anchor reset in base.css\/tokens.css to fall back on. Without\n   these two rules (reference\/home.css offset ~78885) it renders default\n   browser blue-and-underlined \u2014 a palette violation (ivory + black only,\n   taupe on hover) on every page that ships the trust bar. *\/\n.et-l--post a.bk-trust__item {\n  color: inherit;\n  text-decoration: none;\n}\n.et-l--post a.bk-trust__item:hover .t {\n  text-decoration: underline;\n  text-underline-offset: 3px;\n}\n\/* .ic \u2014 the inline SVG icon on non-review items. *\/\n.et-l--post .bk-trust__item .ic {\n  width: 20px;\n  height: 20px;\n  flex: 0 0 auto;\n  color: var(--accent);\n}\n.et-l--post .bk-trust__item .stars {\n  color: var(--accent);\n  letter-spacing: 1.5px;\n  font-size: 14px;\n  line-height: 1;\n}\n\/* .txt is a structural wrapper only \u2014 HOME has no CSS rule for `.txt`\n   itself (Ruling C3); `.t` \/ `.s` below are styled as descendants of\n   `.bk-trust__item`, which still matches through the `.txt` wrapper. *\/\n.et-l--post .bk-trust__item .t {\n  font-family: var(--font-body);\n  font-size: var(--t-ui-size);\n  font-weight: 600;\n  letter-spacing: 0.01em;\n  line-height: 1.25;\n}\n.et-l--post .bk-trust__item .s {\n  font-family: var(--font-body);\n  font-size: var(--t-micro-size);\n  font-weight: 500;\n  color: var(--graphite);\n  line-height: 1.2;\n}\n\n\/* usecases.css \u2014 HOME's \"One Studio, Every Kind of Shoot\" card grid\n   (.who-grid \/ .who-card). Body extracted verbatim from reference\/home.css by\n   tools\/cc_system\/lift.py; every selector scoped to .et-l--post per the\n   project's CSS-specificity rule. Do not hand-edit the rules below \u2014 re-run\n   lift.py --classes who-grid who-card who-card__scrim who-card__txt.\n\n   Why this component exists: measured 2026-09-13 across all 54 EN pages with\n   tools\/cc_system\/vocabulary.py, the use-cases slot renders on HOME and on 11\n   of the 14 service pages, and the system had NO component for it. Every page\n   that wanted one hand-authored its own. That is exactly the D7 defect the\n   system exists to retire.\n\n   Conflicts, enumerated (lift.py reports every duplicate selector, not just the\n   first match):\n     .who-grid            2x \u2014 base (1 column) + @media min-760 (3 columns).\n                               Additive by breakpoint; no conflict.\n     .who-card__txt h3    3x \u2014 base sets font-weight:500; a later compound rule\n                               wins with font-weight:600 !important; a third\n                               sets color:var(--ivory), which .who-card__txt\n                               already supplies by inheritance. All three are\n                               transcribed, because the rule that actually wins\n                               live is the one that must be recorded.\n   No other selector is declared twice. *\/\n.et-l--post .who-grid {\n  display: grid;\n  grid-template-columns: 1fr;\n  gap: 12px;\n  margin-top: 28px;\n}\n.et-l--post .who-card {\n  position: relative;\n  overflow: hidden;\n  aspect-ratio: 3\/2;   \/* declared in direction.json; see its _corrections *\/\n  display: flex;\n  align-items: flex-end;\n}\n\/* Portrait work keeps a portrait frame; measured metadata comes from images.py. *\/\n.et-l--post .who-card:has(img[data-frame-orientation=\"portrait\"]) {\n  aspect-ratio: 4\/5;\n}\n.et-l--post .who-card img {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  transition: transform .9s cubic-bezier(.2,.7,.3,1);\n}\n.et-l--post .who-card:hover img {\n  transform: scale(1.05);\n}\n.et-l--post .who-card__scrim {\n  position: absolute;\n  inset: 0;\n  \/* A SCRIM IS A PERCENTAGE AND A PHOTOGRAPH IS NOT. Retuned 2026-09-14.\n     The 30% start was modelled, never measured against the cards it ships on. The\n     title sits at roughly 61-73% of card height, where the old ramp had reached only\n     alpha ~0.34-0.48 -- so legibility was a property of which photograph landed in\n     the slot. Card 3 (\"Photographers & Video\") draws the brightest frame in the\n     library and measured 5.14:1 at 390; a half-pixel type change elsewhere in this\n     same file moved the text block down a few pixels and it fell to 4.31:1, under\n     the 4.5 floor. A component one rounding error from failing has no margin.\n     The flat zone now starts at 45% and terminates at 0.88, so the title band sits in\n     the opaque part of the ramp rather than on its slope, and the result stops\n     depending on which frame is chosen. Guarded by\n     tests\/test_contrast_over_photos.py, which measures composited pixels.\n     2026-09-25, owner: \"lighten the overlay\" so the photographs read. A percentage\n     ramp cannot do that safely, because the text block's height varies with the copy.\n     \/tour\/'s two-line titles at 844x390 rose into the thin part of the old ramp and\n     measured 1.0-2.6:1 under the 3.0 floor. So the card keeps only a light tone, and\n     the dark fade moves onto .who-card__txt, where it grows with the text it protects.\n     Measured over HOME + \/tour\/, EN\/ES, at all four test viewports: titles >= 6.70:1,\n     descriptions >= 7.14:1. *\/\n  background: linear-gradient(180deg,\n              rgba(11,10,9,0) 50%,\n              rgba(11,10,9,0.20) 100%);\n}\n.et-l--post .who-card__txt {\n  position: relative;\n  z-index: 1;\n  width: 100%;\n  box-sizing: border-box;\n  \/* 2026-10-02, owner: \"Lower the dark overlay ... It needs to see more picture and less words.\" The fade now starts\n     24px above the title instead of 48px (0.64 there) and peaks at 0.72 instead of 0.85; the title is the system h3 role (20-25px,\n     was 22-28px) and the description sits directly under it. Contrast is re-measured by\n     tests\/test_contrast_over_photos.py on composited pixels. *\/\n  padding: var(--s-5) var(--s-4) var(--s-4);\n  color: var(--ivory);\n  background: linear-gradient(180deg,\n              rgba(11,10,9,0) 0,\n              rgba(11,10,9,0.64) var(--s-5),\n              rgba(11,10,9,0.72) 100%);\n}\n\/* 2026-10-04, owner: \"remove the subtext ... just leave the title and lower the overlay even more\" (HOME, then \/tour\/).\n   Without the line the dark band is only as tall as the title, and it peaks at 0.65 instead of 0.72. These titles\n   are 20-25px at weight 600, so their floor is 4.5:1. Measured on composited pixels over every HOME and \/tour\/ card\n   (EN\/ES, four viewports): 0.60 failed (4.31:1, HOME card 1 at 844x390), 0.63 cleared by 6%, 0.65 is kept for\n   headroom. Cards that still carry a line keep the 0.72 fade. Guarded by tests\/test_contrast_over_photos.py. *\/\n.et-l--post .who-card__txt:not(:has(p)) {\n  background: linear-gradient(180deg,\n              rgba(11,10,9,0) 0,\n              rgba(11,10,9,0.58) var(--s-5),\n              rgba(11,10,9,0.65) 100%);\n}\n.et-l--post .who-card__txt h3 {\n  font-family: var(--font-display);\n  font-weight: 500;\n  font-size: var(--t-h3-size);\n  line-height: 1.05;\n  margin: 0;\n  padding: 0;   \/* the theme pads every h3 10px at the bottom, inside this box *\/\n}\n.et-l--post .who-card__txt p {\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 500;\n  opacity: 0.85;\n  margin: 0;\n  line-height: 1.4;\n}\n@media (min-width: 760px) {\n  .et-l--post .who-grid {\n    grid-template-columns: repeat(3,minmax(0,1fr));\n  }\n  \/* This one-sentence audience introduction belongs to the same horizontal\n     axis as the three cards. The global 56ch reading cap made it wrap in the\n     middle of an otherwise open desktop row. *\/\n  .et-l--post [data-screen-label=\"usecases\"] > .container-bk > .bk-lead {\n    max-width: none;\n    text-wrap: pretty;\n  }\n}\n.et-l--post .who-card__txt h3 {\n  font-weight: 600 !important;\n}\n.et-l--post .who-card__txt h3 {\n  color:var(--ivory);\n}\n.et-l--post .who-grid br {\n  display:none;\n}\n\n\/* OWNER-DIRECTED ADDITION, 2026-09-22 -- not a lifted HOME rule.\n   On a phone the three cards were a three-screen stack, so the second and third were\n   a scroll-depth bet. They become one swipeable row: each card 82% of the reading\n   column, so the next one peeks and the affordance is the layout rather than an\n   invented control. Snap points square a card up after a flick; the cards, their\n   scrim and their links are untouched, and desktop keeps HOME's 3-up grid. Keyboard\n   users reach every card by tabbing its link, which scrolls the row. *\/\n@media (max-width: 759px) {\n  .et-l--post .who-grid {\n    grid-template-columns: none;\n    grid-auto-flow: column;\n    grid-auto-columns: 82%;\n    gap: 10px;\n    overflow-x: auto;\n    overscroll-behavior-x: contain;\n    scroll-snap-type: x mandatory;\n    scrollbar-width: none;\n    -webkit-overflow-scrolling: touch;\n  }\n  .et-l--post .who-grid::-webkit-scrollbar {\n    display: none;\n  }\n  .et-l--post .who-grid > .who-card {\n    scroll-snap-align: start;\n  }\n}\n@media (max-width: 759px) and (prefers-reduced-motion: reduce) {\n  .et-l--post .who-grid {\n    scroll-behavior: auto;\n  }\n}\n\n\/* Phase 2 (owner 2026-09-28, rental LP): the value before the price. Round 5, after the owner\n   rejected staging v3 (\"cropping the set\"; \"included ... on the bottom of the sets\" on desktop;\n   spacing not following the system):\n   * every set photo sits in a frame at its NATIVE 3:2, so nothing is cropped (A20 measures it);\n   * HOME's heading rhythm is kept, not overridden: .bk-h2's own 10px + .bk-lead's own 12px, and\n     28px from the lead to the content, as in HOME's use-case section;\n   * phones: one wide lead photo, then two per row, then the inclusions (owner: mobile \"looks fine\");\n   * desktop: three equal columns; the inclusions take the sixth cell beside the last two photos,\n     so the section is one grid on one axis (A21) instead of a list hanging under it.\n   Spacing is HOME's own declarations or --s-* tokens only (tests\/test_new_component_spacing.py). *\/\n.et-l--post .cc-value__sets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5) var(--s-3); margin-top: 28px; }\n.et-l--post .cc-value__set { display: grid; align-content: start; gap: var(--s-2); margin: 0; padding: 0; }\n.et-l--post .cc-value__set:first-child { grid-column: 1 \/ -1; }\n.et-l--post .cc-value__media { aspect-ratio: 3 \/ 2; overflow: hidden; }\n.et-l--post .cc-value__media img { display: block; width: 100%; height: 100%; margin: 0; object-fit: cover; }\n.et-l--post .cc-value__cap { display: flex; align-items: flex-start; gap: var(--s-2); margin: 0; padding: 0; font: 500 14px\/1.4 var(--font-body); color: var(--ink); }\n.et-l--post .cc-value__cap .cc-intro-specs__icon { flex-shrink: 0; width: 20px; height: 20px; }\n.et-l--post .cc-value__group { margin-top: var(--s-6); }\n.et-l--post .cc-value__title { margin: 0 0 var(--s-3); font: 600 16px\/1.375 var(--font-body); color: var(--ink); }\n.et-l--post .cc-value__incl { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-4); }\n.et-l--post .cc-value__incl li { display: flex; align-items: baseline; gap: var(--s-2); margin: 0; padding: 0; font: 500 14px\/1.5 var(--font-body); color: var(--ink); }\n.et-l--post .cc-value__incl li::before { content: \"\"; flex-shrink: 0; width: 6px; height: 6px; background: var(--ink); transform: translateY(-2px); }\n\/* Desktop: one 3x2 grid -- five photos and the inclusions in the sixth cell. *\/\n@media (min-width: 900px) {\n  .et-l--post .cc-value__body { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5) var(--s-3); margin-top: 28px; }\n  .et-l--post .cc-value__sets { display: contents; }\n  .et-l--post .cc-value__set:first-child { grid-column: auto; }\n  .et-l--post .cc-value__cap { font-size: 15px; }\n  .et-l--post .cc-value__group { margin-top: 0; }\n  .et-l--post .cc-value__incl { grid-template-columns: 1fr; gap: var(--s-3); }\n  .et-l--post .cc-value__incl li { font-size: 15px; }\n}\n\n\/* hierarchy.css \u2014 shared corrections and optional compatibility variants.\n   Loaded after component CSS and before states.css.\n\n   Owner correction 2026-09-16: canonical templates preserve HOME's heading\n   family and scale. They do not assign loud\/quiet classes. Composition follows\n   the page's purpose; a mandatory type ladder is not a design requirement.\n   The existing variant declarations below remain for explicit compatibility.\n   Their computed effect depends on the component and the complete cascade. *\/\n\n\/* Optional loud variant; never assigned by canonical templates. *\/\n.et-l--post .bk-section--loud {\n  padding-top: clamp(72px, 12vw, 148px);\n  padding-bottom: clamp(72px, 12vw, 148px);\n}\n\n\/* Legacy heading treatment. Keep its declarations stable for explicit users;\n   normal headings retain HOME's base.css scale. The rendered H1\/H2 relationship\n   is checked at 390 and 1440; a stylesheet clamp alone is not render evidence. *\/\n.et-l--post .bk-section--loud .bk-h2 {\n  font-size: clamp(40px, 6.5vw, 54px);\n  line-height: 1.0;\n  letter-spacing: -0.02em;\n  max-width: 16ch;\n}\n\n.et-l--post .bk-section--loud .bk-lead {\n  font-size: var(--t-lead-size);\n  max-width: 48ch;\n  margin-top: 18px;\n}\n\n\/* Optional quiet spacing; never required as a quota on a page. *\/\n.et-l--post .bk-section--quiet {\n  padding-top: clamp(34px, 5vw, 56px);\n  padding-bottom: clamp(34px, 5vw, 56px);\n}\n\n\/* Legacy quiet heading treatment; no forced ratio against HOME headings. *\/\n.et-l--post .bk-section--quiet .bk-h2 {\n  font-size: clamp(20px, 3vw, 26px);\n  line-height: 1.12;\n  letter-spacing: -0.005em;\n}\n\n\/* Existing phone-width compatibility declarations. *\/\n@media (max-width: 600px) {\n  .et-l--post .bk-section--loud .bk-h2 {\n    font-size: clamp(30px, 8.8vw, 34px);\n    max-width: none;\n  }\n  .et-l--post .bk-section--loud {\n    padding-top: clamp(44px, 9vw, 64px);\n    padding-bottom: clamp(44px, 9vw, 64px);\n  }\n}\n\n\/* Preserve HOME's value-grid and room-card surfaces. Owner direction 2026-09-16\n   supersedes the generic card-fill removal that changed these section designs. *\/\n.et-l--post .shoot-row,\n.et-l--post .step {\n  background: transparent;\n}\n\n\/* DESIGN.md reserves #000000 for brand ink and controls. Preserve the original\n   --accent\/--ash tokens and footer\/sticky declarations; the retired generic\n   pure-black ban must not override them. Section grounds are checked separately. *\/\n\n\/* Existing steps layout. HOME's cards, reviews and other compositions remain\n   governed by their components; generic repeated-layout bans are not authority\n   to redesign them. No automatic emphasis policy depends on this treatment. *\/\n\n\/* STEPS -> a hairline ledger. Three steps are a SEQUENCE, so they get the shape\n   this system already uses for ordered, scannable fact (price, stats): full-width\n   rows, one rule between each, title left and description right. The ordinal is\n   still `display:none` -- steps.css argues at length that the ghost numeral is the\n   banned 01\/02\/03 scaffold, and rank here comes from reading order and the rule,\n   which is what a ledger is for. *\/\n.et-l--post .steps {\n  gap: 0;\n}\n.et-l--post .step {\n  border: 0;\n  border-top: 1px solid var(--line);\n  padding: 20px 0;\n}\n.et-l--post .step:last-child {\n  border-bottom: 1px solid var(--line);\n}\n.et-l--post .step h3 {\n  margin: 0;\n}\n@media (min-width: 760px) {\n  .et-l--post .steps {\n    grid-template-columns: 1fr;\n  }\n  .et-l--post .step {\n    display: grid;\n    grid-template-columns: minmax(0, 24ch) minmax(0, 1fr);\n    gap: 4px 40px;\n    align-items: baseline;\n  }\n}\n\n\/* HOME review cards and use-case columns belong to their components.\n   The editorial quote promotion and asymmetric photo grid were rejected\n   on 2026-09-16; shared overrides must not replace those compositions. *\/\n\n\/* THE SYSTEM SETS ITS OWN BODY TYPEFACE. Added 2026-09-14.\n\n   `.et-l--post` is transcribed from HOME and sets background, font-weight and colour --\n   and no font-family. Only two rules in base.css name a face at all, both for specific\n   elements. So the container inherits whatever the host page provides, and MEASURED on\n   a build with no WordPress theme behind it, `.et-l--post` computes `font-family: Times`\n   and every paragraph in the system renders in it. The headings look right only because\n   `.bk-h2` and `.hm-hero__title` name the display face explicitly.\n\n   On the live site Divi's theme sets a body font, so this has never been visible -- the\n   theme was silently covering for the system. That is the same class of dependency as a\n   mock standing in for a page: it works until the thing underneath changes, and then it\n   fails somewhere nobody was looking. DESIGN.md says \"Montserrat for everything else\";\n   a design system that cannot produce its own body face on a blank page does not own its\n   typography, it borrows it.\n\n   Found by acceptance criterion A17, which reported `body=Times` on every local render\n   and was correct every time. Recorded Divergence from HOME, same basis as the others\n   in this file. *\/\n.et-l--post {\n  font-family: var(--font-body);\n  font-size: var(--t-body-size);\n  line-height: var(--t-body-lh);\n}\n\n\/* THE TRUST STRIP FITS ITS CONTENT. Found 2026-09-15 by looking at the page at 390\n   rather than at a gate: `repeat(3, 1fr)` against a manifest supplying TWO items left\n   a third of the band empty, directly under the hero, on the viewport carrying ~95% of\n   this site's traffic. Every check passed -- `three-equal-cards` needs three children\n   and this has two -- which is exactly the case the render gate exists for.\n\n   `grid-auto-flow: column` with `grid-auto-columns: 1fr` makes one equal track per\n   item, so the component lays out whatever it is given instead of assuming HOME's\n   three. A hardcoded column count in a system component is a content assumption\n   wearing a layout rule. *\/\n.et-l--post .bk-trust__row {\n  grid-template-columns: none;\n  grid-auto-flow: column;\n  grid-auto-columns: 1fr;\n}\n\n\/* THE LEDGER ROW STACKS AT PHONE WIDTH. Found 2026-09-15 by looking at the price\n   section at 390: the row is `1fr auto`, and `auto` sized the price column to 178px\n   against 359px of row, leaving the NAME 126px. \"Full-service session\" in Bodoni at\n   that measure breaks at the hyphen -- \"Full- \/ service \/ session\" -- a legal break\n   that reads as a typesetting accident in display type, on the viewport the owner\n   gates on.\n\n   The price string is the cause: \"$750 \u00b7 2 hours\" is wider than the name it is\n   competing with, so no ratio of fr units fixes it while `auto` wins. Stacking gives\n   the name the full measure and keeps the ledger reading as rows, which is the point\n   of the family. Above 600 the two-column ledger is unchanged. *\/\n@media (max-width: 600px) {\n  .et-l--post .shoot-row {\n    grid-template-columns: 1fr;\n    row-gap: 4px;\n  }\n  \/* The CHILD's explicit placement is what actually holds the two columns open.\n     `grid-template-columns: 1fr` alone changes nothing here: price.css places\n     `.shoot-row__right` at `grid-column: 2; grid-row: 1 \/ span 2`, so the browser\n     creates an IMPLICIT second column sized to the price and the name keeps its 126px.\n     The cascade was never the problem -- the browser confirmed this file's rule was\n     winning while the layout did not move.\n\n     And the placement that needed resetting already existed, in the wrong place:\n     price.css stacks the row inside `@media (min-width: 760px)`, so DESKTOP got the\n     roomy layout with a 28-34px price and MOBILE got the cramped two-column one. On a\n     site where ~95% of traffic is 390 wide, the responsive behaviour was inverted. *\/\n  .et-l--post .shoot-row__right {\n    grid-column: 1;\n    grid-row: auto;\n    margin-top: 12px;\n    justify-content: space-between;\n    width: 100%;\n  }\n}\n\n\/* THE CLOSING CTA PAIR MATCHES ITS OWN WIDTH AT PHONE SIZE. Measured 2026-09-15 at\n   390: the two stacked buttons render 343px and 236px inside a 359px measure -- a\n   107px difference, with a ragged right edge on the last thing the page asks anyone\n   to do. The wider one is near-full only because its label happens to be long; that\n   is an accident of copy, not a decision.\n\n   `btn--block` exists in SYSTEM_ADDITIONS for exactly this reason, recorded there as\n   \"a lone .btn after a full-width block ... strands far short of that block's own\n   right edge\". The same argument applies to a stacked PAIR, and more so: two buttons\n   of different widths read as unfinished in a way one narrow button does not.\n\n   Scoped to `.hm-close .stack-cta` so the hero's side-by-side pair -- which sits in a\n   row and is already balanced -- is untouched. Above 600 both size to their labels as\n   before. *\/\n@media (max-width: 600px) {\n  .et-l--post .hm-close .stack-cta .btn {\n    display: block;\n    width: 100%;\n    text-align: center;\n  }\n}\n\n\/* MEASURE, CAPPED AT DESKTOP. Measured 2026-09-15 at 1440: two body blocks ran past a\n   readable line length -- `.step p` at 884px and `.hm-map__addr` at 1180px, against the\n   65-75 characters this project's own design guidance names. Past roughly 75 the eye\n   loses its place on the return sweep. Neither gate in this system looks at measure.\n\n   The steps one was MINE: the ledger redesign above set `minmax(0, 24ch) minmax(0, 1fr)`\n   and `1fr` handed the description whatever the container had left. Same regression\n   shape as the sticky hover -- correct at the viewport I checked, wrong at the one I\n   did not.\n\n   THREE METRICS WERE WRONG BEFORE ONE WAS RIGHT, which is worth recording because the\n   first two each produced a confident number:\n     width \/ (fontSize * 0.5)   a `ch` is not half the font size; overstated by ~40%\n     characters \/ line count    the AVERAGE, not the longest line -- a 158-character\n                                paragraph over two lines averages 79 while its widest\n                                line holds 66, so it reported a defect that was fixed\n     widest line box \/ measured advance width     what the guideline is actually about\n   Counted that way: the widest line is now 561-584px, about 63-66 characters, and no\n   block at either viewport exceeds 75. *\/\n@media (min-width: 760px) {\n  .et-l--post .step {\n    grid-template-columns: minmax(0, 24ch) minmax(0, 58ch);\n  }\n}\n.et-l--post .hm-map__addr {\n  max-width: 54ch;\n}\n\n\/* THE HERO FITS A LANDSCAPE PHONE. Measured 2026-09-15 at 844x390: the hero renders\n   480px tall on a 390px screen and the CTA ends at 421 -- below the fold. Someone\n   holding their phone sideways sees the headline and no call to action.\n\n   The cause is the unconditional floor in HOME's `clamp(480px, 72svh, 800px)`. At 390\n   tall, 72svh is 281px, so the 480px floor wins and the band is taller than the\n   screen. The floor exists to stop the hero collapsing on short-but-wide viewports;\n   it is the same value that breaks them.\n\n   `min(480px, 88svh)` keeps the floor at 480 everywhere it fits and yields to the\n   viewport where it does not: 343px at 844x390, unchanged at 1440x900 (648) and at\n   390x844 (695, where HOME's own max-width:479px rule governs anyway).\n\n   Acceptance criterion A2 is exactly \"h1+cta above fold\" and would have caught this --\n   it only ever runs at 390x844 and 1440x900. A criterion is only as wide as the\n   viewports it is pointed at. Recorded Divergence from HOME. *\/\n@media (min-width: 480px) {\n  \/* SCOPED to where the base clamp actually governs. Unscoped, this rule is later and\n     equally specific, so it overrode HOME's own `@media (max-width: 479px)` rule --\n     `calc(100svh - 149px)`, which fills the screen minus the mobile header -- and took\n     portrait from 695px to 608px. That is a visible regression at the viewport\n     carrying ~95% of traffic, introduced by a fix for a viewport carrying very little.\n     Caught by measuring all four viewports after the change rather than only the one\n     that was broken. *\/\n  \/* 2026-10-02 (A25, owner: \"flickers\"): 100svh, the height home_fold.js always gave the hero once it ran.\n     The clamp painted 648px at 1440x900 and 343px at 844x390, then the script stretched it to the screen --\n     the same first-paint jump the phone rules caused. min-height still lets a short screen's hero grow to\n     its copy, so the landscape case above keeps its headline and CTA. *\/\n  .et-l--post .hm-hero {\n    min-height: 100svh;\n  }\n}\n\n\/* states.css -- interaction states for every interactive element in the system.\n   \u26a0 THIS FILE IS DESIGNED, NOT TRANSCRIBED. It and prose.css are the only two.\n   Loaded LAST by registry.system_css(), so it can correct a component's own :hover.\n\n   Why it exists: measured 2026-09-13 across the whole system, the ONLY interaction\n   state defined anywhere was :hover. Not one :focus, :focus-visible, :active or\n   :disabled rule existed on any of the five button variants, on the FAQ and spec\n   accordions, or on in-prose links. A keyboard user could not see where they were on\n   seven of fifteen audited pages (0 changed pixels on focus, negative-control\n   verified) -- WCAG 2.4.7 Level AA, failing live.\n\n   ------------------------------------------------------------------------------\n   THE FOCUS RING -- two candidates, both real, one active.\n   The owner picks from the RENDER, not from this comment (styleguide.html renders\n   both, on an ivory ground, on a toned ground, and over a photo hero).\n\n   CANDIDATE A -- \"halo\" (ACTIVE by default below)\n     outline: 2px solid var(--ivory); box-shadow: 0 0 0 5px var(--black);\n     Already shipping on four pages, measured at 17.49:1 on ivory and 16.00:1 on the\n     toned ground. Works over a photograph too, because the ivory inner edge separates\n     the black ring from dark image content. Costs a second shadow, which DESIGN.md's\n     Flat-Editorial Rule otherwise reserves.\n\n   CANDIDATE B -- \"offset rule\" (swap the two blocks below to activate)\n     outline: 3px solid var(--black); outline-offset: 3px;\n     No shadow, so the Flat-Editorial Rule stays intact, and it is one declaration.\n     Weaker over a photographic hero, where a black ring on dark image content loses\n     its edge -- which is exactly where the hero's own CTAs live.\n\n   Both clear 3:1 against every legal ground. :focus-visible, never :focus, so a mouse\n   click does not leave a ring behind -- that is what got focus styling deleted here\n   before, and deleting it is how the WCAG failure started.\n   ------------------------------------------------------------------------------ *\/\n\n\/* Shared halo includes future controls and the global chrome. *\/\n.et-l--post :is(a, button, input, select, textarea, [tabindex], [role=\"button\"]):focus-visible,\n#main-header :focus-visible,\n.stickybar .btn--bar:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: 0;\n  box-shadow: 0 0 0 5px var(--black);\n}\n\n\/* Controls retain their geometry; hit areas do not rely on icon dimensions. *\/\n#main-header .mobile_menu_bar {\n  min-width: 44px;\n  min-height: 44px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  touch-action: manipulation;\n}\n#main-header:has(.mobile_nav.opened) .logo_container #logo,\n#main-header:has(.mobile_nav.opened) .logo_container #logo img {\n  filter: none !important;\n}\n.et-l--post .gal-tab {\n  min-width: 44px;\n  min-height: 44px;\n  touch-action: manipulation;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .et-l--post *,\n  .et-l--post *::before,\n  .et-l--post *::after,\n  #main-header,\n  #main-header *,\n  .stickybar,\n  .stickybar * {\n    animation: none !important;\n    transition-duration: 0s !important;\n    scroll-behavior: auto !important;\n  }\n}\n\n\/* A focus ring must never be clipped by an ancestor's overflow. .who-card sets\n   overflow:hidden for its image zoom, which would shear the ring off. *\/\n.et-l--post .who-card:focus-visible {\n  overflow: visible;\n}\n\n\/* ---- :active -------------------------------------------------------------\n   .btn:hover lifts the button 2px. Without an :active rule the button stays\n   lifted while being pressed, so a press reads as no feedback at all. Return it\n   to rest: the press is the only moment the control should sit flat. *\/\n.et-l--post .btn:active,\n.stickybar .btn--bar:active {\n  transform: translateY(0);\n  transition-duration: .05s;\n}\n\n\/* ---- :disabled -----------------------------------------------------------\n   Nothing in the system disables a control today, but the sticky bar and the\n   booking CTAs are the obvious future case, and an undefined disabled state\n   renders as a fully live-looking button that silently does nothing. *\/\n.et-l--post .btn:disabled,\n.et-l--post .btn[aria-disabled=\"true\"] {\n  opacity: 0.45;\n  cursor: not-allowed;\n  pointer-events: none;\n  transform: none;\n}\n\n\/* DESIGN.md: true-black labels on clay for primary hover and keyboard focus.\n   Full opacity preserves the measured 5.53:1 contrast. The shared halo above\n   remains the focus indicator; controls retain their position. *\/\n.et-l--post .btn--solid:not(:disabled):not([aria-disabled=\"true\"]):is(:hover, :focus-visible) {\n  background: #8D8175 !important;\n  border-color: #8D8175;\n  color: var(--accent) !important;\n  opacity: 1;\n  transform: none;\n}\n.stickybar .btn--bar:is(:hover, :focus-visible) {\n  background: #8D8175;\n  border-color: #8D8175;\n  color: var(--accent);\n}\n\n\/* ---- BLOCK-LEVEL CARD ANCHORS ------------------------------------------------\n   base.css carries HOME's rule `.et-l--post a { text-decoration: underline }`, which\n   is right for a bare link inside a sentence and wrong for every anchor that is a\n   CARD. .shoot-row, .who-card and .gal-tab are block elements that happen to be\n   anchors; inheriting a prose underline, they render with every line of their content\n   underlined -- the package name, the meta line and the price all struck through with\n   a rule.\n\n   Found 2026-09-14 by rendering the price ladder and looking at it. The tell that\n   someone hit this before and patched the symptom: trust.css already carries a\n   bespoke `a.bk-trust__item { text-decoration: none }` for exactly one component.\n   This fixes it at the root for the whole class of element, so the next card anchor\n   added does not need its own override.\n\n   Prose links are untouched: .bk-prose a sets its own border-bottom, and a bare <a>\n   in any other copy still underlines as HOME intends. *\/\n.et-l--post a.shoot-row,\n.et-l--post a.who-card,\n.et-l--post a.gal-tab,\n.et-l--post a.hm-close,\n.et-l--post a.stat {\n  text-decoration: none;\n}\n\n\n\/* ---- THE STICKY BAR IS NOT INSIDE .et-l--post -------------------------------\n   sticky.html ends with `document.body.appendChild(bar)`, so the bar is a direct child\n   of <body>. Every rule above that targets it therefore had to drop the .et-l--post\n   scope, and the focus-ring selector list had to gain it explicitly -- its anchor\n   carries class=\"btn--bar\", not .btn, so even an unscoped .btn rule would have missed.\n\n   This was found on 2026-09-14 by a review, not by me. The contrast correction directly\n   above it was written earlier the same day, carefully documented, and was DEAD CODE\n   from the moment it was committed: a rule that cannot match is worth exactly as much\n   as a comment. It is the same failure this repo's render gate exists to prevent --\n   asserting on a document that is not the page -- committed while fixing that class of\n   failure elsewhere.\n\n   The bar is the only control present on all 48 pages. Until now it had no focus\n   indicator at all. *\/\n\n\/* The global popup sits outside .et-l--post. Specificity must beat its own\n   later body stylesheet, so every control rule includes the existing card. *\/\n#cc10 .cc10-card .cc10-x {\n  width: 44px;\n  height: 44px;\n  min-width: 44px;\n  min-height: 44px;\n}\n#cc10 .cc10-card :is(button, input, a, [tabindex]):focus-visible {\n  outline: 2px solid var(--ivory, #F9F0E0);\n  outline-offset: 0;\n  box-shadow: 0 0 0 5px var(--black, #0B0A09);\n}\n@media (prefers-reduced-motion: reduce) {\n  #cc10 .cc10-card,\n  #cc10 .cc10-card *,\n  #cc10 .cc10-backdrop {\n    transition: none !important;\n    animation: none !important;\n    scroll-behavior: auto !important;\n  }\n}\n<\/style><script>\/* Enhance Divi's existing header. Divi remains the sole owner of click toggling\n   and slide animation; replacing its trigger would discard attached behavior. *\/\n(function () {\n  'use strict';\n\n  function enhanceHeader() {\n    var header = document.getElementById('main-header');\n    var pageHero = document.querySelector('.et-l--post [data-nav-context]');\n    var context = pageHero && pageHero.getAttribute('data-nav-context');\n    if (header && (context === 'light' || context === 'media')) {\n      header.setAttribute('data-cc-nav-context', context);\n    }\n    var nav = header && header.querySelector('.mobile_nav');\n    if (header) {\n      header.querySelectorAll('.wpml-ls-current-language > a').forEach(function (link) {\n        link.setAttribute('aria-current', 'page');\n      });\n    }\n    var trigger = nav && nav.querySelector('.mobile_menu_bar');\n    if (!trigger || trigger.dataset.ccNavEnhanced) return;\n    trigger.dataset.ccNavEnhanced = 'true';\n\n    var mobile = window.matchMedia('(max-width: 980px)');\n    var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');\n    var spanish = \/^es(?:-|$)\/i.test(document.documentElement.lang);\n    var nativeButton = trigger.tagName === 'BUTTON';\n    var spacePressed = false;\n    var lastHeaderFocus = null;\n    if (!nativeButton) trigger.setAttribute('role', 'button');\n    else trigger.type = 'button';\n\n    function menu() {\n      return nav.querySelector('.et_mobile_menu');\n    }\n\n    function isOpen() {\n      return nav.classList.contains('opened');\n    }\n\n    function sync() {\n      var panel = menu();\n      var expanded = mobile.matches && isOpen();\n      trigger.tabIndex = mobile.matches ? 0 : -1;\n      trigger.setAttribute('aria-expanded', String(expanded));\n      trigger.setAttribute('aria-label', spanish\n        ? (expanded ? 'Cerrar men\u00fa' : 'Abrir men\u00fa')\n        : (expanded ? 'Close menu' : 'Open menu'));\n      if (!panel) return;\n      if (!panel.id) panel.id = 'cc-header-mobile-menu';\n      trigger.setAttribute('aria-controls', panel.id);\n      \/\/ Keep closed links out of focus and the accessibility tree even during\n      \/\/ Divi's 500ms closing animation. Do not override its display\/height.\n      panel.inert = !expanded;\n      panel.setAttribute('aria-hidden', String(!expanded));\n      \/\/ Class observation runs after Divi schedules its slide. Finish only this\n      \/\/ panel's queue; never disable jQuery effects across the rest of the page.\n      if (reducedMotion.matches && typeof window.jQuery === 'function') {\n        window.jQuery(panel).stop(true, true);\n      }\n    }\n\n    function close() {\n      if (isOpen()) trigger.click();\n      sync();\n    }\n\n    if (!nativeButton) {\n      trigger.addEventListener('keydown', function (event) {\n        if (event.key === 'Enter' || event.key === ' ') {\n          event.preventDefault();\n          if (event.repeat) return;\n          if (event.key === 'Enter') trigger.click();\n          else spacePressed = true;\n        }\n      });\n      trigger.addEventListener('keyup', function (event) {\n        if (event.key !== ' ') return;\n        event.preventDefault();\n        if (spacePressed) trigger.click();\n        spacePressed = false;\n      });\n      trigger.addEventListener('blur', function () { spacePressed = false; });\n    }\n\n    document.addEventListener('keydown', function (event) {\n      if (event.key !== 'Escape' || !mobile.matches || !isOpen()) return;\n      event.preventDefault();\n      close();\n      trigger.focus({preventScroll: true});\n    });\n    document.addEventListener('pointerdown', function (event) {\n      if (mobile.matches && isOpen() && !header.contains(event.target)) close();\n    }, true);\n    document.addEventListener('focusin', function (event) {\n      lastHeaderFocus = header.contains(event.target) ? event.target : null;\n    });\n    window.addEventListener('resize', function () {\n      var panel = menu();\n      var active = document.activeElement;\n      if (mobile.matches && isOpen() && panel && panel.contains(active)) {\n        active.scrollIntoView({block: 'nearest', inline: 'nearest'});\n      }\n    });\n\n    mobile.addEventListener('change', function () {\n      var active = document.activeElement;\n      \/\/ A CSS breakpoint can hide the focused link before this event fires,\n      \/\/ making activeElement the body. Retain only a just-hidden header focus.\n      if (active === document.body && lastHeaderFocus &&\n          !lastHeaderFocus.getClientRects().length) active = lastHeaderFocus;\n      var activeInMobile = nav.contains(active);\n      var desktop = header.querySelector('#top-menu');\n      var activeInDesktop = desktop && desktop.contains(active);\n      var href = active && active.getAttribute('href');\n      close();\n      if (!mobile.matches && activeInMobile && desktop) {\n        var links = Array.from(desktop.querySelectorAll('a[href]'));\n        var next = links.find(function (link) {\n          return link.getAttribute('href') === href;\n        }) || links[0];\n        if (next) next.focus({preventScroll: true});\n      } else if (mobile.matches && activeInDesktop) {\n        trigger.focus({preventScroll: true});\n      }\n    });\n\n    \/\/ Divi may duplicate the desktop menu after this script has initialized.\n    \/\/ Observe both that insertion and Divi's authoritative open\/closed class.\n    new MutationObserver(sync).observe(nav, {\n      attributes: true, attributeFilter: ['class'], childList: true, subtree: true\n    });\n    reducedMotion.addEventListener('change', sync);\n    sync();\n  }\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', enhanceHeader, {once: true});\n  } else {\n    enhanceHeader();\n  }\n})();\n\n\/* Complete cc10's existing modal behavior. Its original script continues to\n   own opening, closing, submission, success, copying, and analytics. *\/\n(function () {\n  'use strict';\n\n  function enhanceDialog() {\n    var root = document.getElementById('cc10');\n    var card = root && root.querySelector('.cc10-card');\n    if (!card || root.dataset.ccDialogEnhanced) return;\n    root.dataset.ccDialogEnhanced = 'true';\n    var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');\n    var video = root.querySelector('video');\n    var hadAutoplay = video && video.autoplay;\n    var field = root.querySelector('.cc10-field');\n    var email = root.querySelector('#cc10-email');\n\n    function isOpen() {\n      return root.hasAttribute('data-open') && root.getAttribute('aria-hidden') !== 'true';\n    }\n\n    function controls() {\n      return Array.from(card.querySelectorAll('a[href],button,input,select,textarea,[tabindex]'))\n        .filter(function (element) {\n          return element.tabIndex >= 0 && !element.disabled &&\n            !element.closest('[hidden],[aria-hidden=\"true\"],[inert]') &&\n            element.getClientRects().length && getComputedStyle(element).visibility !== 'hidden';\n        });\n    }\n\n    function syncVideo() {\n      if (!video) return;\n      var canAutoplay = isOpen() && !reducedMotion.matches && hadAutoplay;\n      video.autoplay = Boolean(canAutoplay);\n      if (!canAutoplay) video.pause();\n      else if (video.paused) video.play().catch(function () { \/* Browser may block autoplay. *\/ });\n    }\n\n    function syncState() {\n      root.inert = !isOpen();\n      if (isOpen() && !root.contains(document.activeElement)) {\n        card.focus({preventScroll: true});\n      }\n      syncVideo();\n    }\n\n    \/\/ The original trap already wraps the first\/last controls. It misses the\n    \/\/ initially focused tabindex=-1 card, so handle only that entry case.\n    document.addEventListener('keydown', function (event) {\n      if (event.key !== 'Tab' || !isOpen()) return;\n      var list = controls();\n      if (list.includes(document.activeElement)) return;\n      event.preventDefault();\n      var target = event.shiftKey ? list[list.length - 1] : list[0];\n      (target || card).focus({preventScroll: true});\n    }, true);\n    document.addEventListener('focusin', function (event) {\n      if (!isOpen() || root.contains(event.target)) return;\n      \/\/ The original legacy-copy path briefly selects an offscreen textarea.\n      \/\/ Let that synchronous operation finish before restoring modal focus.\n      queueMicrotask(function () {\n        if (isOpen() && !root.contains(document.activeElement)) card.focus({preventScroll: true});\n      });\n    });\n\n    if (field && email) {\n      var syncError = function () {\n        email.setAttribute('aria-invalid', String(field.classList.contains('is-bad')));\n      };\n      new MutationObserver(syncError).observe(field, {attributes: true, attributeFilter: ['class']});\n      syncError();\n    }\n    if (video) {\n      video.addEventListener('play', function () {\n        if (!isOpen() || reducedMotion.matches) video.pause();\n      });\n    }\n    reducedMotion.addEventListener('change', syncVideo);\n    new MutationObserver(syncState).observe(root, {\n      attributes: true, attributeFilter: ['data-open', 'aria-hidden']\n    });\n    syncState();\n  }\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', enhanceDialog, {once: true});\n  } else {\n    enhanceDialog();\n  }\n})();\n\n\/* Size a media hero to the first screen, less the trust strip below it while a page still has one\n   (owner 2026-09-30, Crown: the strip is retired under the system hero); short screens may grow for content. *\/\nfunction initHomeFold() {\n  document.querySelectorAll('.et-l--post .hm-hero').forEach(function (hero) {\n    if (hero.hasAttribute('data-fold-ready')) return;\n    var section = hero.closest('.et_pb_section');\n    var trust = section && section.nextElementSibling && section.nextElementSibling.querySelector('.bk-trust');\n    hero.setAttribute('data-fold-ready', '');\n    var content = hero.querySelector('.hm-hero__in');\n    var lastViewportWidth = window.visualViewport ? window.visualViewport.width : window.innerWidth;\n    function measure() {\n      var top = hero.getBoundingClientRect().top + window.scrollY;\n      var nav = document.getElementById('main-header');\n      var clearance = nav ? nav.getBoundingClientRect().height + 24 : 32;\n      var minimum = content.getBoundingClientRect().height + clearance;\n      var below = trust ? trust.getBoundingClientRect().height : 0;\n      var height = Math.max(minimum, window.innerHeight - top - below);\n      hero.style.setProperty('--cc-hero-fold', height + 'px');\n    }\n    function measureForWidthChange() {\n      var viewportWidth = window.visualViewport ? window.visualViewport.width : window.innerWidth;\n      if (Math.abs(viewportWidth - lastViewportWidth) < 1) return;\n      lastViewportWidth = viewportWidth;\n      measure();\n    }\n    var observer = new ResizeObserver(measure);\n    if (trust) observer.observe(trust);\n    observer.observe(content);\n    window.addEventListener('resize', measureForWidthChange, {passive: true});\n    document.fonts.ready.then(measure);\n    measure();\n  });\n}\nif (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initHomeFold, {once: true});\nelse initHomeFold();\n\n\n\/* Progressive enhancement: the photo-led option becomes a keyboard-operable guide. *\/\n(function () {\n  function init() {\n    document.querySelectorAll('[data-intro-tabs]').forEach(function (root, rootIndex) {\n      if (root.dataset.introReady) return;\n      root.dataset.introReady = 'true';\n      var details = Array.from(root.querySelectorAll('details'));\n      var nav = document.createElement('div');\n      var pricing = root.classList.contains('cc-intro-pricing');\n      \/* Owner 2026-09-22: the pricing guide uses HOME's own two-cell tab bar\n         (.price-tabs, uppercase label over a small subtitle) instead of the\n         underline tabs. price.css hides a .price-tabs until it is marked ready. *\/\n      nav.className = pricing ? 'price-tabs' : 'cc-intro-tabs'; nav.setAttribute('role', 'tablist');\n      if (pricing) nav.setAttribute('data-cc-price-ready', '');\n      nav.setAttribute('aria-label', document.documentElement.lang === 'es' ? (pricing ? 'Opciones de precios' : 'Gu\u00eda del estudio') : (pricing ? 'Pricing options' : 'Studio guide'));\n      var buttons = [], panels = [];\n      details.forEach(function (detail, index) {\n        var prefix = 'studio-guide-' + rootIndex + '-' + index;\n        var button = document.createElement('button'); button.type = 'button';\n        button.textContent = detail.querySelector('summary strong').textContent;\n        if (pricing) {\n          button.className = 'price-tab'; button.setAttribute('data-panel', prefix);\n          var subtitle = detail.querySelector('summary small');\n          if (subtitle && subtitle.textContent.trim()) {\n            var small = document.createElement('small'); small.textContent = subtitle.textContent.trim();\n            button.appendChild(small);\n          }\n        }\n        button.id = prefix + '-tab'; button.setAttribute('role', 'tab');\n        button.setAttribute('aria-controls', prefix + '-panel');\n        var panel = document.createElement('div'); panel.id = prefix + '-panel';\n        panel.className = 'cc-intro-tabpanel'; panel.setAttribute('role', 'tabpanel');\n        panel.setAttribute('aria-labelledby', button.id); panel.tabIndex = 0;\n        panel.appendChild(detail.querySelector('.cc-intro-detail__body'));\n        detail.replaceWith(panel); nav.appendChild(button); buttons.push(button); panels.push(panel);\n        button.addEventListener('click', function () { select(index); });\n        button.addEventListener('keydown', function (event) {\n          var target;\n          if (event.key === 'ArrowRight') target = (index + 1) % buttons.length;\n          if (event.key === 'ArrowLeft') target = (index - 1 + buttons.length) % buttons.length;\n          if (event.key === 'Home') target = 0;\n          if (event.key === 'End') target = buttons.length - 1;\n          if (target !== undefined) { event.preventDefault(); select(target); buttons[target].focus(); }\n        });\n      });\n      function select(index) {\n        buttons.forEach(function (button, i) {\n          button.setAttribute('aria-selected', String(i === index)); button.tabIndex = i === index ? 0 : -1;\n          panels[i].hidden = i !== index;\n        });\n      }\n      root.prepend(nav); select(0);\n      root._ccTabs = {nav: nav, buttons: buttons, select: select};\n    });\n  }\n  \/* Owner 2026-09-27 (rental LP): a link to \"#tab-<label>\" opens that tab, e.g. the hero's\n     \"Book a Photoshoot\" -> #tab-photoshoots. No other link on the site uses the prefix. *\/\n  \/* The site header is fixed; land the tab bar just under it rather than at a guessed offset,\n     so no line of the guide is left half-hidden behind it. *\/\n  function headerBottom() {\n    var el = document.elementFromPoint(window.innerWidth \/ 2, 1);\n    for (; el && el !== document.body; el = el.parentElement) {\n      var position = getComputedStyle(el).position;\n      if (position === 'fixed' || position === 'sticky') return Math.max(0, el.getBoundingClientRect().bottom);\n    }\n    return 0;\n  }\n  function slug(text) { return text.toLowerCase().replace(\/[^a-z0-9]+\/g, '-').replace(\/^-|-$\/g, ''); }\n  function openTab(hash) {\n    if (!\/^#tab-[a-z0-9-]+$\/.test(hash || '')) return false;\n    var key = hash.slice(5), hit = null;\n    document.querySelectorAll('[data-intro-tabs]').forEach(function (root) {\n      if (hit || !root._ccTabs) return;\n      root._ccTabs.buttons.forEach(function (button, index) {\n        if (!hit && slug(button.childNodes[0].textContent) === key) hit = {root: root, index: index, button: button};\n      });\n    });\n    if (!hit) return false;\n    var holder = hit.root.closest('details');\n    if (holder) holder.open = true;\n    hit.root._ccTabs.select(hit.index);\n    var smooth = !window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n    var top = hit.root._ccTabs.nav.getBoundingClientRect().top + window.scrollY - headerBottom() - 12;\n    window.scrollTo({top: Math.max(0, top), behavior: smooth ? 'smooth' : 'auto'});\n    hit.button.focus({preventScroll: true});\n    return true;\n  }\n  document.addEventListener('click', function (event) {\n    var link = event.target.closest && event.target.closest('a[href^=\"#tab-\"]');\n    if (link && openTab(link.getAttribute('href'))) event.preventDefault();\n  });\n  function initAll() { init(); if (location.hash) openTab(location.hash); }\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initAll, {once: true});\n  else initAll();\n})();\n\n(function () {\n  if (window.ccGalleryRuntimeReady) return;\n  window.ccGalleryRuntimeReady = true;\n\n  var spanish = (document.documentElement.lang || \"\").toLowerCase().indexOf(\"es\") === 0;\n  var labels = spanish ? {\n    viewer: \"Visor de im\u00e1genes de la galer\u00eda\",\n    open: \"Ampliar imagen\",\n    close: \"Cerrar visor de im\u00e1genes\",\n    previous: \"Imagen anterior\",\n    next: \"Imagen siguiente\",\n    of: \"de\"\n  } : {\n    viewer: \"Gallery image viewer\",\n    open: \"Expand image\",\n    close: \"Close image viewer\",\n    previous: \"Previous image\",\n    next: \"Next image\",\n    of: \"of\"\n  };\n\n  function imageUrl(image) {\n    return image.getAttribute(\"data-lazy-src\") ||\n      image.getAttribute(\"data-src\") || image.currentSrc || image.src;\n  }\n\n  function isImageLink(link) {\n    if (!link) return false;\n    var href = link.getAttribute(\"href\") || \"\";\n    return \/\\\/wp-content\\\/uploads\\\/\/i.test(href) ||\n      \/\\.(?:avif|gif|jpe?g|png|webp)(?:[?#].*)?$\/i.test(href);\n  }\n\n  function sourceUrl(item) {\n    return isImageLink(item.link) ? item.link.href : imageUrl(item.image);\n  }\n\n  function makeDialog(root) {\n    var dialog = document.createElement(\"dialog\");\n    dialog.className = \"gal-lightbox\";\n    dialog.setAttribute(\"aria-label\", labels.viewer);\n    dialog.innerHTML =\n      '<button type=\"button\" class=\"gal-lightbox__close\" aria-label=\"' + labels.close + '\">&times;<\/button>' +\n      '<div class=\"gal-lightbox__stage\">' +\n        '<button type=\"button\" class=\"gal-lightbox__nav gal-lightbox__prev\" aria-label=\"' + labels.previous + '\">\u2190<\/button>' +\n        '<figure><img alt=\"\" draggable=\"false\"><\/figure>' +\n        '<button type=\"button\" class=\"gal-lightbox__nav gal-lightbox__next\" aria-label=\"' + labels.next + '\">\u2192<\/button>' +\n        '<div class=\"gal-lightbox__status\" role=\"status\" aria-live=\"polite\"><\/div>' +\n      '<\/div>';\n    root.appendChild(dialog);\n    return dialog;\n  }\n\n  function legacyItems(root, featured) {\n    var selector = featured ? \".gal-item img\" : \".gal-grid > figure img\";\n    return Array.prototype.slice.call(root.querySelectorAll(selector)).map(function (image) {\n      var link = image.closest(\"a\");\n      if (link && !isImageLink(link)) return null;\n      return { image: image, link: link, opener: null };\n    }).filter(Boolean);\n  }\n\n  function prepareOpener(item) {\n    var opener = item.link || item.image.closest(\"button\");\n    if (!opener) {\n      opener = document.createElement(\"button\");\n      opener.type = \"button\";\n      opener.className = \"gal-open\";\n      var media = item.image.closest(\"picture\") || item.image;\n      media.parentNode.insertBefore(opener, media);\n      opener.appendChild(media);\n    }\n    opener.setAttribute(\"data-cc-gallery-open\", \"\");\n    opener.setAttribute(\"aria-label\", labels.open + \": \" + item.image.alt);\n    item.opener = opener;\n  }\n\n  function initLegacy(root, featured) {\n    if (!root || root.hasAttribute(\"data-cc-gallery-runtime\")) return;\n    var items = legacyItems(root, featured);\n    if (!items.length) return;\n    root.setAttribute(\"data-cc-gallery-runtime\", \"\");\n    items.forEach(prepareOpener);\n\n    var dialog = makeDialog(root);\n    var viewedImage = dialog.querySelector(\"img\");\n    var status = dialog.querySelector(\".gal-lightbox__status\");\n    var closeButton = dialog.querySelector(\".gal-lightbox__close\");\n    var previousButton = dialog.querySelector(\".gal-lightbox__prev\");\n    var nextButton = dialog.querySelector(\".gal-lightbox__next\");\n    var stage = dialog.querySelector(\".gal-lightbox__stage\");\n    var current = 0;\n    var opener = null;\n    var lockedScrollX = 0;\n    var lockedScrollY = 0;\n    var neighborPreloads = [];\n\n    function preloadNeighbors() {\n      neighborPreloads = [-1, 1].map(function (offset) {\n        var preload = new Image();\n        preload.decoding = \"async\";\n        preload.src = sourceUrl(items[(current + offset + items.length) % items.length]);\n        return preload;\n      });\n    }\n\n    function showAt(index) {\n      current = (index + items.length) % items.length;\n      viewedImage.src = sourceUrl(items[current]);\n      viewedImage.alt = items[current].image.alt;\n      status.textContent = (current + 1) + \" \" + labels.of + \" \" + items.length;\n      preloadNeighbors();\n    }\n\n    function lockPage() {\n      lockedScrollX = window.scrollX;\n      lockedScrollY = window.scrollY;\n      document.documentElement.classList.add(\"gal-lightbox-open\");\n      document.body.classList.add(\"gal-lightbox-open\");\n    }\n\n    function unlockPage() {\n      document.documentElement.classList.remove(\"gal-lightbox-open\");\n      document.body.classList.remove(\"gal-lightbox-open\");\n      window.scrollTo(lockedScrollX, lockedScrollY);\n    }\n\n    root.addEventListener(\"click\", function (event) {\n      var target = event.target.closest(\"[data-cc-gallery-open]\");\n      if (!target || !root.contains(target)) return;\n      event.preventDefault();\n      event.stopPropagation();\n      opener = target;\n      var index = items.findIndex(function (item) { return item.opener === target; });\n      if (index < 0) return;\n      showAt(index);\n      lockPage();\n      dialog.showModal();\n      closeButton.focus({ preventScroll: true });\n    }, true);\n\n    previousButton.addEventListener(\"click\", function () { showAt(current - 1); });\n    nextButton.addEventListener(\"click\", function () { showAt(current + 1); });\n    closeButton.addEventListener(\"click\", function () { dialog.close(); });\n    dialog.addEventListener(\"click\", function (event) {\n      if (event.target === dialog) dialog.close();\n    });\n    dialog.addEventListener(\"close\", function () {\n      unlockPage();\n      if (opener && opener.isConnected) opener.focus({ preventScroll: true });\n    });\n    dialog.addEventListener(\"cancel\", unlockPage);\n    dialog.addEventListener(\"keydown\", function (event) {\n      if (event.key === \"ArrowRight\") { event.preventDefault(); showAt(current + 1); return; }\n      if (event.key === \"ArrowLeft\") { event.preventDefault(); showAt(current - 1); return; }\n      if (event.key !== \"Tab\") return;\n      var controls = [closeButton, previousButton, nextButton];\n      if (event.shiftKey && document.activeElement === controls[0]) {\n        event.preventDefault(); controls[2].focus();\n      } else if (!event.shiftKey && document.activeElement === controls[2]) {\n        event.preventDefault(); controls[0].focus();\n      }\n    });\n\n    var pointer = null;\n    stage.addEventListener(\"pointerdown\", function (event) {\n      if (event.button !== undefined && event.button !== 0) return;\n      if (event.target.closest(\"button\")) return;\n      pointer = { id: event.pointerId, x: event.clientX, y: event.clientY };\n      try { stage.setPointerCapture(event.pointerId); } catch (error) {}\n    });\n    stage.addEventListener(\"pointerup\", function (event) {\n      if (!pointer || pointer.id !== event.pointerId) return;\n      var dx = event.clientX - pointer.x;\n      var dy = event.clientY - pointer.y;\n      pointer = null;\n      try { stage.releasePointerCapture(event.pointerId); } catch (error) {}\n      if (Math.abs(dx) < 44 || Math.abs(dx) < Math.abs(dy) * 1.2) return;\n      showAt(current + (dx < 0 ? 1 : -1));\n    });\n    stage.addEventListener(\"pointercancel\", function (event) {\n      pointer = null;\n      try { stage.releasePointerCapture(event.pointerId); } catch (error) {}\n    });\n  }\n\n  function repairSystemViewer(gallery) {\n    var dialog = gallery.querySelector(\".gal-lightbox\");\n    if (!dialog || dialog.hasAttribute(\"data-cc-lazy-repair\")) return;\n    dialog.setAttribute(\"data-cc-lazy-repair\", \"\");\n    var viewedImage = dialog.querySelector(\"figure img\");\n    var status = dialog.querySelector(\".gal-lightbox__status\");\n    var sources = gallery.querySelectorAll(\".gal-grid > figure img, .gal-grid > .gal-rail > figure img\");\n    function repair() {\n      var match = status && status.textContent.match(\/^\\s*(\\d+)\/);\n      if (!match) return;\n      var source = sources[Number(match[1]) - 1];\n      if (!source) return;\n      var correct = imageUrl(source);\n      if (correct && viewedImage.getAttribute(\"src\") !== correct) viewedImage.src = correct;\n    }\n    new MutationObserver(repair).observe(dialog, {\n      subtree: true, childList: true, characterData: true, attributes: true,\n      attributeFilter: [\"src\"]\n    });\n    repair();\n  }\n\n  function start() {\n    document.querySelectorAll(\"[data-gallery]\").forEach(repairSystemViewer);\n    document.querySelectorAll(\"#gal-section.gal-sec, .cc-portfolio\").forEach(function (root) {\n      initLegacy(root, true);\n    });\n    document.querySelectorAll(\".gal-grid\").forEach(function (grid) {\n      if (grid.closest(\"[data-gallery], #gal-section.gal-sec, .cc-portfolio\")) return;\n      initLegacy(grid.closest(\"section\") || grid.parentElement || grid, false);\n    });\n  }\n\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n  } else {\n    start();\n  }\n})();\n<\/script><style>\/* usecases `features` (owner 2026-10-06, video page: \"Below it add the list of things with icons\"). The list is HOME's\n   own studio-guide group, styled by HOME's own intro_editorial rules through the .cc-intro--editorial class it carries\n   (round 4, owner: \"not following brand guidelines and font heiarchy\" -- nothing is restyled here). The one rule:\n   HOME's 28px from a section's lead to its content (usecases.css, value_intro.css), from the cards to the list.\n   Ships only where a usecases section places features, so HOME and \/tour\/ are byte-identical. *\/\n.et-l--post .cc-uc-feat { margin-top: 28px; }\n<\/style><style>\/* Studio-guide lists without icons (owner 2026-10-06, video page: \"what crews shoot here should be copy instead of\n   assets\"). HOME's list puts each title in a 22px icon column beside it and indents the text 34px to match; with no\n   icon the title fell into the 22px column, one word per line. A plain list gives the title the full width and drops\n   the indent. Everything else -- type, gaps, columns -- is HOME's own rule. Ships only where a plain list exists. *\/\n\/* Round 3 (owner 2026-10-06: \"what shoots here section is really important\"): each title is a search term, so it\n   reads as one -- the display face at HOME's h3 role, not the 16px label weight. *\/\n.et-l--post .cc-intro--editorial .cc-intro-specs.cc-intro-specs--plain dt { display: block; }\n.et-l--post .cc-intro--editorial .cc-intro-specs.cc-intro-specs--plain dd { margin: 0; }\n<\/style><style>\/* Owner 2026-10-07 (video page): \"No tab for rates\", then \"The price chart is different look and feel from home\".\n   A price ledger shown without HOME's tab bar must read as HOME's chart: no guide hairline doubling its own ink rule,\n   and a line under it 16px below, exactly as \/rates\/ sets them. Both declarations live in intro_ledger.css, which\n   ships only with the \/rates\/ ledger layout; this sheet carries them verbatim wherever a bare ledger is placed and\n   no section uses that layout. *\/\n.et-l--post .cc-intro--editorial .cc-intro-details:has(> .cc-rates:first-child) { border-top: 0; }\n.et-l--post .cc-intro--editorial .cc-intro-details > .cc-rates ~ p { margin-top: var(--s-4); }\n<\/style><style>\/* Wide clips (owner 2026-10-06, video page: \"yes add one to handle mobile first\"): the client productions are 16:9.\n   Phones: one clip at 78vw so about 40px of the next one peeks. Desktop: two 584px clips exactly fill the 1180px\n   container with the rail's 12px gap; the frame is 16:9 like the clip, so the cover is never cropped.\n   Ships only where a reels section names aspect \"16:9\" (build.py), so Christmas stays byte-identical. *\/\n\/* Two classes: the base reels sheet ships after this one at equal specificity (build.py order). *\/\n.et-l--post .cc-reels.cc-reels--wide {\n  --reel-w: clamp(250px, 78vw, 584px);\n}\n.et-l--post .cc-reels--wide .cc-reel__frame {\n  aspect-ratio: 16 \/ 9;\n}\n.et-l--post .cc-reels--wide .cc-reels__nav {\n  top: calc(var(--reel-w) * 9 \/ 16 \/ 2 - 24px);\n}\n\/* Round 4 (owner: \"space is not from brand rules\"): a reels heading sat 0px on the clips. HOME's heading-to-media gap\n   is 20px (\"Tour the Studio\" to its video, measured 2026-10-06 at 390 and 1440). This sheet ships wherever a reels\n   section carries a heading or the 16:9 aspect. *\/\n.et-l--post .cc-reels .bk-h2 + .cc-reels__stage { margin-top: 20px; }\n<\/style><style>\/* Christmas reels (owner 2026-10-05, direction A \"peek rail\"): vertical 9:16 reels in a rail, tap-to-play.\n   Page-scoped (components.json scope \"page\"): ships only where a section places it. Composed from the set rail\n   (gallery.css .gal-rail: 12px gap, x snap, hidden scrollbar; .gal-railnav__btn: the 48px square arrow) and HOME's\n   square brand button. Phones: each reel is about two-thirds of the screen, so the next one peeks and the rail reads\n   as swipeable. Desktop: 286px reels, four exactly fill the 1180px container; a shorter row centres, a longer one\n   scrolls behind the arrows. The frame is 9:16 like the reel, so the cover is never cropped. *\/\n.et-l--post .cc-reels {\n  --reel-w: clamp(220px, 66vw, 286px);\n}\n.et-l--post .cc-reels__stage {\n  position: relative;\n}\n.et-l--post .cc-reels__rail {\n  display: flex;\n  gap: var(--s-3);\n  min-width: 0;\n  overflow-x: auto;\n  overscroll-behavior-x: contain;\n  scroll-snap-type: x mandatory;\n  scroll-behavior: smooth;\n  scrollbar-width: none;\n}\n.et-l--post .cc-reels__rail::-webkit-scrollbar {\n  display: none;\n}\n.et-l--post .cc-reels__rail:focus-visible {\n  outline: 2px solid var(--ink);\n  outline-offset: 4px;\n}\n.et-l--post .cc-reel {\n  display: flex;\n  flex: 0 0 var(--reel-w);\n  flex-direction: column;\n  gap: var(--s-2);\n  margin: 0;\n  scroll-snap-align: start;\n}\n\/* A row shorter than the container centres; the auto margins collapse to 0 once the rail overflows. *\/\n.et-l--post .cc-reel:first-child {\n  margin-left: auto;\n}\n.et-l--post .cc-reel:last-child {\n  margin-right: auto;\n}\n.et-l--post .cc-reel__frame {\n  position: relative;\n  aspect-ratio: 9 \/ 16;\n  overflow: hidden;\n  background: var(--ivory-deep);\n}\n.et-l--post .cc-reel__video {\n  display: block;\n  width: 100%;\n  height: 100%;\n  max-width: none;\n  object-fit: cover;\n}\n\/* The play button sits in the frame's lower-left corner, not its centre: reels burn their titles into the middle of\n   the frame (staging 2026-10-05: a centred button covered the Nutcracker reel's opening line). *\/\n.et-l--post .cc-reel__play {\n  position: absolute;\n  left: var(--s-3);\n  bottom: var(--s-3);\n  display: grid;\n  place-items: center;\n  width: 56px;\n  height: 56px;\n  min-height: 56px;\n  margin: 0;\n  padding: 0;\n  border: 0;\n  border-radius: 0;\n  background: rgba(249,240,224,.92);\n  color: var(--ink);\n  cursor: pointer;\n  transition: background-color 0.2s;\n}\n.et-l--post .cc-reel__play:hover {\n  background: #8D8175;\n}\n.et-l--post .cc-reel__play:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: 3px;\n}\n.et-l--post .cc-reel__play svg {\n  width: 18px;\n  height: 18px;\n  margin-left: 3px;\n}\n.et-l--post .cc-reel.is-playing .cc-reel__play {\n  display: none;\n}\n.et-l--post .cc-reel__label {\n  margin: 0;\n  padding: 0;\n  font-family: var(--font-body);\n  font-size: var(--t-meta-size);\n  font-weight: 600;\n  line-height: var(--t-meta-lh);\n  color: var(--ink);\n}\n\/* The rail's arrows: the set rail's square arrow, centred on the reel frames (not the labels under them). *\/\n.et-l--post .cc-reels__nav {\n  position: absolute;\n  top: calc(var(--reel-w) * 16 \/ 9 \/ 2 - 24px);\n  left: 0;\n  right: 0;\n  display: flex;\n  justify-content: space-between;\n  padding: 0 var(--s-2);\n  pointer-events: none;\n}\n.et-l--post .cc-reels__btn {\n  display: grid;\n  place-items: center;\n  width: 48px;\n  height: 48px;\n  min-height: 48px;\n  padding: 0;\n  border: 1px solid rgba(249,240,224,.55);\n  border-radius: 0;\n  background: rgba(11,10,9,.72);\n  color: var(--ivory);\n  font-family: var(--font-body);\n  font-size: var(--t-h3-size);\n  line-height: 1;\n  cursor: pointer;\n  pointer-events: auto;\n}\n.et-l--post .cc-reels__btn[hidden] {\n  display: none;\n}\n.et-l--post .cc-reels__next {\n  margin-left: auto;\n}\n.et-l--post .cc-reels__btn:hover {\n  border-color: #8D8175;\n  background: #8D8175;\n}\n.et-l--post .cc-reels__btn:focus-visible {\n  outline: 2px solid var(--ivory);\n  outline-offset: 2px;\n}\n<\/style><!-- HOME hero: decorative media behind an accessible heading, copy and links. -->\n<div class=\"hm-hero\" data-screen-label=\"hero\" data-nav-context=\"media\">\n<picture class=\"hm-bgpic\"><source media=\"(max-width: 759px)\" srcset=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-rental-miami-fashion-trio-mobile-centered.webp\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/white-cyclorama-wall-photography-lighting-miami-studio-1.webp\" alt=\"Estudio de fotograf\u00eda y video: nuestro ciclorama blanco, iluminado y listo para grabar\" width=\"1920\" height=\"1080\" fetchpriority=\"high\" decoding=\"async\" data-no-lazy=\"1\" data-frame-orientation=\"landscape\" style=\"object-position:48% 51%\"><\/picture>\n<div class=\"hm-scrim\"><\/div>\n<div class=\"hm-hero__in\">\n<h1 class=\"hm-hero__title\" id=\"hero-title\"><span class=\"hm-hero__line\">Tu estudio<\/span> <span class=\"hm-hero__line\">de fotograf\u00eda y video<\/span><\/h1>\n<p class=\"hm-hero__sub\">Renta todo el estudio desde $110 la hora entre semana y $130 el fin de semana. \u00bfQuieres que lo grabemos por ti? Preg\u00fantanos por la producci\u00f3n de video.<\/p>\n<p class=\"hm-hero__reviews\"><span><span class=\"hm-hero__stars\" aria-hidden=\"true\">\u2605\u2605\u2605\u2605\u2605<\/span><span class=\"hm-hero__reviews-label\">300+ rese\u00f1as de 5 estrellas en Google<\/span><\/span><\/p>\n<div class=\"hm-hero__actions \">\n<a class=\"btn btn--invert\" href=\"\/es\/reservar\/?book=rental&amp;entry=video&amp;cta=hero-rental#book\">Reservar el estudio<span class=\"arrow\" aria-hidden=\"true\">\u2192<\/span><\/a>\n<\/div>\n<\/div><\/div>\n<script>(function () {\n  var hero = document.currentScript.previousElementSibling;\n  var video = hero.querySelector('.hm-bgvid');\n  if (!video) { return; }\n  var preference = window.matchMedia('(prefers-reduced-motion: reduce)');\n  function sync() {\n    if (preference.matches) { video.pause(); }\n    else { video.play().catch(function () {}); }\n  }\n  preference.addEventListener('change', sync);\n  sync();\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_1 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--std\" id=\"space\"><div class=\"et_pb_row_1 et_pb_row et_block_row\"><div class=\"et_pb_column_1 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_1 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight\" data-screen-label=\"usecases\" aria-labelledby=\"space-title\">\n<div class=\"container-bk reveal\">\n<h2 class=\"bk-h2\" id=\"space-title\">Sets de video incluidos<\/h2>\n<p class=\"bk-lead\">Renta de sets para video con todo incluido: el ciclorama blanco de 25\u2032 \u00d7 20\u2032, dos sets de arcos y escenarios decorados, para varios looks en una sola reserva.<\/p>\n<!-- card shape: <a class=\"who-card\" href=\"\/target\/\"><img decoding=\"async\" src=\"URL\" alt=\"Describes the shoot, not the file\" loading=\"lazy\" width=\"800\" height=\"500\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>Use case<\/h3><p>One line on who it is for.<\/p><\/div><\/a>, one per use case. Three cards read as one row at 760px and up; four wrap to 3+1 and look broken -- ship three or six. -->\n<div class=\"who-grid\"><a class=\"who-card\" href=\"\/es\/renta-de-ciclorama-miami\/\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/white-cyclorama-wall-posing-platform-miami-studio-1.webp\" width=\"2048\" height=\"1367\" alt=\"Ciclorama blanco con plataforma curva para posar y luces de estudio en un estudio de fotos en Miami\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 55%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>El ciclorama<\/h3><\/div><\/a><div class=\"who-card\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/09\/studio-poster.jpg\" width=\"800\" height=\"450\" alt=\"Muro de tres arcos con un sof\u00e1 curvo caf\u00e9 y una silla de director en un estudio de fotos en Miami\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 55%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>Pared de arcos<\/h3><\/div><\/div><div class=\"who-card\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/white-arch-riser-platform-set-miami-photo-studio-1.webp\" width=\"2048\" height=\"1367\" alt=\"Plataforma escultural blanca con arco, flores y espejo ondulado en un estudio en Miami\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 58%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>Sets decorados<\/h3><\/div><\/div><div class=\"who-card\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/sheer-curtain-backdrop-armchairs-miami-studio-1.webp\" width=\"2048\" height=\"1367\" alt=\"Sillones de madera color crema frente a cortinas transl\u00facidas en un estudio luminoso en Miami\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 55%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>Rinc\u00f3n de luz natural<\/h3><\/div><\/div><div class=\"who-card\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/lounge-set-beige-sofa-fireplace-mirror-miami-studio-1.webp\" width=\"2048\" height=\"1367\" alt=\"Set lounge con sof\u00e1 beige capitonado, chimenea tallada y espejo dorado en un estudio en Miami\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 55%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>El set lounge<\/h3><\/div><\/div><div class=\"who-card\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/photo-studio-with-free-parking-miami-easy-load-in.jpg\" width=\"1600\" height=\"1067\" alt=\"Rack de rollos de papel de fondo en rojo, azul, rosa, lila y verde\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:40% 55%\"><div class=\"who-card__scrim\"><\/div><div class=\"who-card__txt\"><h3>Fondos de papel<\/h3><\/div><\/div><\/div><div class=\"cc-intro--editorial cc-uc-feat\"><div class=\"cc-intro-details\"><details class=\"cc-intro-detail\" open><summary><strong>Listo para video<\/strong><i aria-hidden=\"true\"><\/i><\/summary><div class=\"cc-intro-detail__body\"><dl class=\"cc-intro-specs\"><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3.5 7.5h13v13h-13z\"\/><path d=\"M3.5 3.5h13\"\/><path d=\"M3.5 2.5v2M16.5 2.5v2\"\/><path d=\"M20.5 7.5v13\"\/><path d=\"M19.5 7.5h2M19.5 20.5h2\"\/><\/svg><\/span>3,000 pies\u00b2, todo tuyo<\/dt><dd>Todo el estudio privado durante tu reserva.<\/dd><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5.5 3.5h13v9h-13z\"\/><path d=\"M8.5 6.5h7M8.5 9.5h7\"\/><path d=\"M12 12.5v8\"\/><path d=\"M8 20.5h8\"\/><\/svg><\/span>Luces y grip incluidos<\/dt><dd>Listos para usar. La lista completa est\u00e1 abajo.<\/dd><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 14.5A8.5 8.5 0 0 1 9.5 4a8.5 8.5 0 1 0 10.5 10.5z\"\/><\/svg><\/span>Cortinas blackout<\/dt><dd>Cierra las siete ventanas para controlar cada luz.<\/dd><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 8.5a3 3 0 1 0 6 0a3 3 0 1 0-6 0\"\/><path d=\"M3.5 20.5a6 6 0 0 1 12 0\"\/><path d=\"M15 6.6a2.6 2.6 0 1 1 1 5\"\/><path d=\"M17.5 14.5a5 5 0 0 1 3 6\"\/><\/svg><\/span>Espacio para 15 personas<\/dt><dd>Equipo y talento juntos. Preg\u00fantanos si son m\u00e1s.<\/dd><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 9.5a5.5 5.5 0 0 1 11 0v11h-11z\"\/><path d=\"M4.5 20.5h15\"\/><\/svg><\/span>Estaci\u00f3n de maquillaje<\/dt><dd>Con Wi-Fi, A\/C y snacks para el equipo.<\/dd><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3.5 12a8.5 8.5 0 1 0 17 0a8.5 8.5 0 1 0-17 0\"\/><path d=\"M12 7v5l3.5 2\"\/><\/svg><\/span>Abierto 24\/7<\/dt><dd>Acceso reservado de d\u00eda o de noche, a la misma tarifa por hora.<\/dd><\/div><\/dl><\/div><\/details><\/div><\/div>\n<\/div>\n<\/section>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_2 et_pb_section et_section_regular et_block_section\" id=\"shoots\"><div class=\"et_pb_row_2 et_pb_row et_block_row\"><div class=\"et_pb_column_2 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_2 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section cc-intro cc-intro--editorial\" data-intro-layout=\"text\" data-screen-label=\"intro_editorial\">\n<div class=\"container-bk cc-intro-grid\">\n<header class=\"cc-intro-heading\"><h2>Lo que se graba aqu\u00ed<\/h2><p>Nuestro estudio de fotograf\u00eda y video en Miami se renta por hora. Artistas, marcas y creadores lo reservan como estudio audiovisual porque los sets, las luces y el grip ya est\u00e1n aqu\u00ed.<\/p><\/header>\n<figure class=\"cc-intro-photo\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/07\/img_1581-e1783557884340.jpg\" alt=\"Sof\u00e1 curvo caf\u00e9 bajo el set de tres arcos en CC Studios Miami\" width=\"1850\" height=\"960\" loading=\"lazy\" decoding=\"async\"><\/figure>\n<div class=\"cc-intro-details\"><details class=\"cc-intro-detail\" open><summary><strong>Producciones que recibimos<\/strong><i aria-hidden=\"true\"><\/i><\/summary><div class=\"cc-intro-detail__body\"><dl class=\"cc-intro-specs cc-intro-specs--plain\"><div><dt>Estudio para videos musicales<\/dt><dd>Artistas y directores reservan todo el estudio para las tomas de presentaci\u00f3n y las escenas de la historia en un solo d\u00eda. Se permiten el humo y la niebla, y las luces RGB cambian de color desde tu tel\u00e9fono.<\/dd><\/div><div><dt>Producci\u00f3n de comerciales<\/dt><dd>Las marcas graban spots para TV y redes con su propio equipo, varios spots en una sola reserva. \u00bfQuieres que lo produzcamos? <a href=\"\/es\/contacto\/\">Pregunta por la producci\u00f3n de video<\/a>.<\/dd><\/div><div><dt>Videos testimoniales de marca<\/dt><dd>Fundadores y clientes cuentan la historia de la marca a c\u00e1mara y luego muestran el producto en la misma sesi\u00f3n.<\/dd><\/div><div><dt>Entrevistas a c\u00e1mara<\/dt><dd>Entrevistas, videos de expertos y paneles, con cortinas blackout para una luz estable y repetible. \u00bfGrabas un programa? Mira nuestro <a href=\"\/es\/estudio-de-podcast-miami\/\">estudio de podcast<\/a>.<\/dd><\/div><div><dt>Videos de producto y demos<\/dt><dd>Demos, unboxings y versiones cortas para anuncios de marcas de e-commerce, grabados en la misma reserva que las fotos del lanzamiento.<\/dd><\/div><div><dt>Recaps de eventos y lanzamientos<\/dt><dd>Lanzamientos, pop-ups y celebraciones en el estudio, grabados para redes y los canales de la marca.<\/dd><\/div><\/dl><\/div><\/details><\/div>\n<\/div>\n<\/section>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_3 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--std\" id=\"clips\"><div class=\"et_pb_row_3 et_pb_row et_block_row\"><div class=\"et_pb_column_3 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_3 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight cc-reels cc-reels--wide\" data-screen-label=\"reels\" aria-label=\"Videos grabados en el estudio\">\n<div class=\"container-bk reveal\">\n<h2 class=\"bk-h2\" id=\"clips-title\">Videos grabados aqu\u00ed<\/h2><div class=\"cc-reels__stage\">\n<!-- item shape: <figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"COVER\" src=\"MP4\" aria-label=\"ALT\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: LABEL\">...<\/button><\/div><figcaption class=\"cc-reel__label\">LABEL<\/figcaption><\/figure> -->\n<div class=\"cc-reels__rail\" role=\"region\" tabindex=\"0\" aria-label=\"Videos grabados en el estudio\"><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-music-video-rick-ross-gold-bottle-wall-cover.jpg\" aria-label=\"Video musical grabado en nuestro estudio de fotograf\u00eda y video: Finesse2tymes y Rick Ross frente a la pared de botellas doradas\" data-youtube=\"QpxzctZ4bmU\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Video musical ft. Rick Ross\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Video musical ft. Rick Ross<\/figcaption><\/figure><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama-cover.jpg\" src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama.mp4\" aria-label=\"Comercial grabado en nuestro estudio de fotograf\u00eda y video: tres presentadores de traje en el ciclorama blanco, con un close-up del producto\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Comercial\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Comercial<\/figcaption><\/figure><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set-cover.jpg\" src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set.mp4\" aria-label=\"Testimonio de marca grabado en el set de arcos de nuestro estudio de fotograf\u00eda y video, con una demostraci\u00f3n del producto en el sof\u00e1\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Testimonio de marca\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Testimonio de marca<\/figcaption><\/figure><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama-cover.jpg\" src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama.mp4\" aria-label=\"Entrevista grabada en el ciclorama blanco de nuestro estudio de fotograf\u00eda y video: dos personas en sillones de piel\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Entrevista\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Entrevista<\/figcaption><\/figure><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set-cover.jpg\" src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set.mp4\" aria-label=\"Recap de evento grabado en nuestro estudio de fotograf\u00eda y video: un set de cena, un perchero, una sesi\u00f3n grupal y un set de pastel\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Recap de evento\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Recap de evento<\/figcaption><\/figure><figure class=\"cc-reel\"><div class=\"cc-reel__frame\"><video class=\"cc-reel__video\" preload=\"none\" playsinline poster=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel-cover.jpg\" src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel.mp4\" aria-label=\"Reel de nuestro estudio de fotograf\u00eda y video: entrevistas, testimonios, detr\u00e1s de c\u00e1maras y campa\u00f1as\"><\/video><button type=\"button\" class=\"cc-reel__play\" aria-label=\"Play: Reel del estudio\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M7 4l13 8-13 8z\" fill=\"currentColor\"><\/path><\/svg><\/button><\/div><figcaption class=\"cc-reel__label\">Reel del estudio<\/figcaption><\/figure><\/div>\n<div class=\"cc-reels__nav\"><button type=\"button\" class=\"cc-reels__btn cc-reels__prev\" aria-label=\"Previous reels\" hidden>\u2190<\/button><button type=\"button\" class=\"cc-reels__btn cc-reels__next\" aria-label=\"Next reels\">\u2192<\/button><\/div>\n<\/div>\n<\/div>\n<\/section>\n<script>(function () {\n  \/\/ Owner 2026-10-05 (Christmas reels, direction A): tap-to-play. Nothing but the cover still loads until a tap\n  \/\/ (preload=\"none\"); one reel plays at a time; the rail's arrows page it like the set rails and hide at each end.\n  var script = document.currentScript;\n  var section = script && script.previousElementSibling;\n  if (!section || !section.classList.contains(\"cc-reels\") || section.hasAttribute(\"data-reels-ready\")) return;\n  section.setAttribute(\"data-reels-ready\", \"\");\n  var rail = section.querySelector(\".cc-reels__rail\");\n  var previous = section.querySelector(\".cc-reels__prev\");\n  var next = section.querySelector(\".cc-reels__next\");\n  var reels = Array.prototype.slice.call(section.querySelectorAll(\".cc-reel\"));\n  if ((document.documentElement.lang || \"\").toLowerCase().indexOf(\"es\") === 0) {\n    previous.setAttribute(\"aria-label\", \"Reels anteriores\");\n    next.setAttribute(\"aria-label\", \"Reels siguientes\");\n    reels.forEach(function (reel) {\n      var play = reel.querySelector(\".cc-reel__play\");\n      play.setAttribute(\"aria-label\", play.getAttribute(\"aria-label\").replace(\/^Play:\/, \"Reproducir:\"));\n    });\n  }\n\n  reels.forEach(function (reel) {\n    var video = reel.querySelector(\"video\");\n    var play = reel.querySelector(\".cc-reel__play\");\n    play.addEventListener(\"click\", function () {\n      reels.forEach(function (other) {\n        if (other !== reel) other.querySelector(\"video\").pause();\n      });\n      reel.classList.add(\"is-playing\");\n      video.controls = true;\n      var started = video.play();\n      if (started && started.catch) started.catch(function () {});\n    });\n    video.addEventListener(\"ended\", function () {\n      reel.classList.remove(\"is-playing\");\n      video.controls = false;\n      video.load();\n    });\n  });\n\n  function setHidden(button, hidden, other) {\n    if (button.hidden === hidden) return;\n    if (hidden && document.activeElement === button && !other.hidden) other.focus({ preventScroll: true });\n    button.hidden = hidden;\n  }\n  function sync() {\n    var end = rail.scrollWidth - rail.clientWidth - 1;\n    setHidden(previous, rail.scrollLeft <= 1, next);\n    setHidden(next, rail.scrollLeft >= end, previous);\n  }\n  function go(direction) {\n    var here = rail.scrollLeft;\n    var origin = rail.getBoundingClientRect().left - here;\n    var starts = reels.map(function (reel) { return reel.getBoundingClientRect().left - origin; });\n    var target = direction > 0\n      ? starts.filter(function (start) { return start > here + 1; })[0]\n      : starts.filter(function (start) { return start < here - 1; }).pop();\n    rail.scrollTo({ left: target === undefined ? (direction > 0 ? rail.scrollWidth : 0) : target });\n  }\n  previous.addEventListener(\"click\", function () { go(-1); });\n  next.addEventListener(\"click\", function () { go(1); });\n  rail.addEventListener(\"scroll\", sync, { passive: true });\n  if (typeof ResizeObserver === \"function\") new ResizeObserver(sync).observe(rail);\n  sync();\n})();<\/script><script>(function () {\n  \/* Owner 2026-10-07 (video page): \"add this video first in videos shot in the studio. Rick Ross music video\" -- a\n     YouTube video. A reel whose <video> carries data-youtube shows our cover still; only after a tap does the video\n     play in place, in the same player the 3D tour's Short uses. The reels script beside this one still owns the rail,\n     the arrows and every MP4 reel; this one only swaps the YouTube player in, and out again when another reel plays. *\/\n  var script = document.currentScript;\n  var section = script && script.previousElementSibling && script.previousElementSibling.previousElementSibling;\n  if (!section || !section.classList.contains(\"cc-reels\")) return;\n  var reels = Array.prototype.slice.call(section.querySelectorAll(\".cc-reel\"));\n  function stop(reel) {\n    var frame = reel.querySelector(\"iframe\");\n    if (!frame) return;\n    frame.remove();\n    reel.querySelector(\"video\").hidden = false;\n    reel.classList.remove(\"is-playing\");\n  }\n  reels.forEach(function (reel) {\n    var video = reel.querySelector(\"video[data-youtube]\");\n    var play = reel.querySelector(\".cc-reel__play\");\n    play.addEventListener(\"click\", function () {\n      reels.forEach(function (other) { if (other !== reel) stop(other); });\n      if (!video || reel.querySelector(\"iframe\")) return;\n      video.controls = false;\n      video.hidden = true;\n      var frame = document.createElement(\"iframe\");\n      frame.className = \"cc-reel__video\";\n      frame.src = \"https:\/\/www.youtube.com\/embed\/\" + video.dataset.youtube + \"?autoplay=1&playsinline=1&rel=0\";\n      frame.title = reel.querySelector(\".cc-reel__label\").textContent.trim() + \" \u2014 YouTube\";\n      frame.allow = \"autoplay; encrypted-media; picture-in-picture; fullscreen\";\n      frame.setAttribute(\"allowfullscreen\", \"\");\n      frame.style.border = \"0\";\n      video.parentNode.insertBefore(frame, video);\n      frame.focus();\n    });\n  });\n})();\n<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_4 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--std\" id=\"tour\"><div class=\"et_pb_row_4 et_pb_row et_block_row\"><div class=\"et_pb_column_4 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_4 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight cc-explore\" data-screen-label=\"explore3d\" data-room-layout=\"walkthrough\" aria-labelledby=\"tour-title\">\n<div class=\"container-bk\">\n<h2 class=\"bk-h2\" id=\"tour-title\">Recorre el estudio<\/h2>\n<div class=\"space-feat space-feat--solo\">\n<div class=\"space-feat__media\"><div class=\"cc-tourvid\" data-explore-src=\"https:\/\/my.matterport.com\/show\/?m=qZagjrsW6Tm&amp;play=1&amp;qs=1\" data-explore-loading=\"Abriendo el tour 3D\">\n<a class=\"cc-yt-facade cc-explore__start\" href=\"https:\/\/my.matterport.com\/show\/?m=qZagjrsW6Tm\" target=\"_blank\" rel=\"noopener\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/09\/cc-studios-miami-matterport-3d-tour.webp\" alt=\"Dentro de CC Studios Miami: los sets de arcos, las ventanas con cortinas y el ciclorama en un mismo espacio abierto\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\" data-frame-orientation=\"landscape\" style=\"object-position:50% 50%\"><span class=\"btn btn--solid cc-explore__label\"><span class=\"cc-explore__text\">Explorar en 3D<\/span><span class=\"arrow\" aria-hidden=\"true\">\u2192<\/span><\/span><\/a>\n<\/div><\/div>\n<\/div>\n<p class=\"cc-explore__more\"><a class=\"cc-explore__play\" href=\"https:\/\/www.youtube.com\/shorts\/oxFz2ffWe7U\" target=\"_blank\" rel=\"noopener\" data-explore-video=\"oxFz2ffWe7U\">O mira el tour de dos minutos<\/a><\/p>\n<\/div>\n<\/section>\n<script>(function () {\n  \/* Owner 2026-09-28: the 3D tour stays on the page and starts in place on a tap, in HOME's tour\n     frame (the same facade HOME's \"Tour the Studio\" video uses). Round 9: \"Lets do the matterport\n     here instead of dollhouse\" -- the viewer is the owner's Matterport. The tour Short opens under\n     it, vertical, in place (\"as long as it stays on the page\"). *\/\n  var section = document.currentScript.previousElementSibling;\n  var stage = section.querySelector('.cc-tourvid');\n  var start = stage.querySelector('.cc-explore__start');\n  start.addEventListener('click', function (event) {\n    event.preventDefault();\n    var player = document.createElement('div');\n    player.className = 'cc-yt-facade';\n    player.appendChild(start.querySelector('img').cloneNode());\n    var label = start.querySelector('.cc-explore__label').cloneNode(true);\n    label.querySelector('.cc-explore__text').textContent = stage.dataset.exploreLoading;\n    player.appendChild(label);\n    var frame = document.createElement('iframe');\n    frame.className = 'cc-explore__frame';\n    frame.title = start.querySelector('.cc-explore__text').textContent.trim();\n    frame.allow = 'fullscreen; xr-spatial-tracking';\n    frame.setAttribute('allowfullscreen', '');\n    \/* The provider is another origin, so its load event is the only signal; 20 s still reveals it. *\/\n    var timer;\n    function ready() { clearTimeout(timer); stage.dataset.state = 'ready'; }\n    frame.addEventListener('load', ready, {once: true});\n    timer = setTimeout(ready, 20000);\n    \/* Round 10 (owner: \"how do i get it to stay on page?\"): Matterport plays in place on a phone only\n       when its frame covers at least 60% of the screen, and otherwise sends the visitor to its own\n       page. The phone frame opens to 64% of the screen before the viewer measures itself (CSS applies\n       it below 760px only; desktop's 16:9 frame already qualifies). *\/\n    stage.style.setProperty('--cc-explore-open', Math.ceil(screen.height * 0.64) + 'px');\n    stage.dataset.state = 'loading';\n    frame.src = stage.dataset.exploreSrc;\n    player.appendChild(frame);\n    start.replaceWith(player);\n    if (window.matchMedia('(max-width: 759px)').matches) {\n      var still = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n      player.scrollIntoView({block: 'center', behavior: still ? 'auto' : 'smooth'});\n    }\n  }, {once: true});\n  var play = section.querySelector('.cc-explore__play');\n  play.addEventListener('click', function (event) {\n    event.preventDefault();\n    var frame = document.createElement('iframe');\n    frame.className = 'cc-explore__vframe';\n    frame.src = 'https:\/\/www.youtube.com\/embed\/' + play.dataset.exploreVideo + '?autoplay=1&playsinline=1&rel=0';\n    frame.title = play.textContent.trim() + ' \u2014 YouTube';\n    frame.allow = 'autoplay; encrypted-media; picture-in-picture; fullscreen';\n    frame.setAttribute('allowfullscreen', '');\n    play.parentElement.replaceWith(frame);\n    frame.focus();\n  }, {once: true});\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_5 et_pb_section et_section_regular et_block_section\" id=\"rates\"><div class=\"et_pb_row_5 et_pb_row et_block_row\"><div class=\"et_pb_column_5 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_5 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section cc-intro cc-intro--editorial\" data-intro-layout=\"text\" data-screen-label=\"intro_editorial\">\n<div class=\"container-bk cc-intro-grid\">\n<header class=\"cc-intro-heading\"><h2>Tarifas del estudio<\/h2><p>Renta todo el estudio por hora, m\u00ednimo una hora, a la misma tarifa de d\u00eda o de noche.<\/p><\/header>\n<figure class=\"cc-intro-photo\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/07\/img_1581-e1783557884340.jpg\" alt=\"Sof\u00e1 curvo caf\u00e9 bajo el set de tres arcos en CC Studios Miami\" width=\"1850\" height=\"960\" loading=\"lazy\" decoding=\"async\"><\/figure>\n<div class=\"cc-intro-details\"><div class=\"cc-rates\"><table><thead><tr><th scope=\"col\">Horas<\/th><th scope=\"col\">Entre semana<\/th><th scope=\"col\">Fin de semana<\/th><\/tr><\/thead><tbody><tr><th scope=\"row\">1 hora<\/th><td>$110<\/td><td>$130<\/td><\/tr><tr><th scope=\"row\">2 horas<\/th><td>$220<\/td><td>$260<\/td><\/tr><tr><th scope=\"row\">3 horas<\/th><td>$320<\/td><td>$390<\/td><\/tr><tr class=\"cc-rates__feat\"><th scope=\"row\">4 horas <span class=\"shoot-row__flag\">M\u00e1s reservado<\/span><\/th><td>$410<\/td><td>$500<\/td><\/tr><tr><th scope=\"row\">5 horas<\/th><td>$500<\/td><td>$610<\/td><\/tr><tr><th scope=\"row\">6 horas<\/th><td>$590<\/td><td>$720<\/td><\/tr><tr><th scope=\"row\">7 horas<\/th><td>$670<\/td><td>$830<\/td><\/tr><tr><th scope=\"row\">8 horas<\/th><td>$750<\/td><td>$930<\/td><\/tr><\/tbody><\/table><\/div><p>\u00bfQuieres que produzcamos tu video? <a href=\"\/es\/contacto\/\">Cont\u00e1ctanos directamente<\/a> y cotizamos tu proyecto.<\/p><div class=\"rent-foot\"><a class=\"btn btn--solid\" href=\"\/es\/reservar\/?book=rental&amp;entry=video&amp;cta=rates-rental#book\">Reservar el estudio <span class=\"arrow\" aria-hidden=\"true\">\u2192<\/span><\/a><\/div><\/div>\n<\/div>\n<\/section>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_6 et_pb_section et_section_regular et_block_section\" id=\"gear\"><div class=\"et_pb_row_6 et_pb_row et_block_row\"><div class=\"et_pb_column_6 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_6 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section cc-intro cc-intro--editorial\" data-intro-layout=\"text\" data-screen-label=\"intro_editorial\">\n<div class=\"container-bk cc-intro-grid\">\n<header class=\"cc-intro-heading\"><h2>Equipo incluido<\/h2><p>Las luces de video y el grip vienen incluidos con cada renta y montados en el estudio. Trae tu c\u00e1mara, tu audio y tu equipo.<\/p><\/header>\n<figure class=\"cc-intro-photo\"><img src=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/07\/img_1581-e1783557884340.jpg\" alt=\"Sof\u00e1 curvo caf\u00e9 bajo el set de tres arcos en CC Studios Miami\" width=\"1850\" height=\"960\" loading=\"lazy\" decoding=\"async\"><\/figure>\n<div class=\"cc-intro-details\"><details class=\"cc-intro-detail\" open><summary><strong>Luces y modificadores<\/strong><i aria-hidden=\"true\"><\/i><\/summary><div class=\"cc-intro-detail__body\"><dl class=\"cc-intro-specs\"><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 8a5.5 5.5 0 1 0 11 0a5.5 5.5 0 1 0-11 0\"\/><path d=\"M9.5 8a2.5 5.5 0 1 0 5 0a2.5 5.5 0 1 0-5 0\"\/><path d=\"M6.5 8h11\"\/><path d=\"M12 13.5v7\"\/><path d=\"M8.5 20.5h7\"\/><\/svg><\/span>3 luces RGB GVM SD300C<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 8a5.5 5.5 0 1 0 11 0a5.5 5.5 0 1 0-11 0\"\/><path d=\"M9.5 8a2.5 5.5 0 1 0 5 0a2.5 5.5 0 1 0-5 0\"\/><path d=\"M6.5 8h11\"\/><path d=\"M12 13.5v7\"\/><path d=\"M8.5 20.5h7\"\/><\/svg><\/span>3 paneles LED GVM 1200D<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5.5 3.5h13v9h-13z\"\/><path d=\"M8.5 6.5h7M8.5 9.5h7\"\/><path d=\"M12 12.5v8\"\/><path d=\"M8 20.5h8\"\/><\/svg><\/span>2 luces LED GVM de 150W<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3.5 8.5h6v7h-6z\"\/><path d=\"M9.5 9.5l9 1.5v2l-9 1.5\"\/><path d=\"M6.5 15.5v5M4.5 20.5h4\"\/><\/svg><\/span>Accesorio snoot<\/dt><\/div><\/dl><\/div><\/details><details class=\"cc-intro-detail\" open><summary><strong>Flashes y grip<\/strong><i aria-hidden=\"true\"><\/i><\/summary><div class=\"cc-intro-detail__body\"><dl class=\"cc-intro-specs\"><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13.5 2.5 6.5 13.5h5l-1 8 7-11h-5z\"\/><\/svg><\/span>Godox AD400 Pro II<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13.5 2.5 6.5 13.5h5l-1 8 7-11h-5z\"\/><\/svg><\/span>Godox SK400II-V<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3.5v10\"\/><path d=\"M8.5 5.5h7\"\/><path d=\"M12 13.5l-6.5 7\"\/><path d=\"M12 13.5l6.5 7\"\/><path d=\"M12 13.5v7\"\/><\/svg><\/span>4 C-stands con ruedas<\/dt><\/div><\/dl><\/div><\/details><details class=\"cc-intro-detail\" open><summary><strong>Equipo de producci\u00f3n<\/strong><i aria-hidden=\"true\"><\/i><\/summary><div class=\"cc-intro-detail__body\"><dl class=\"cc-intro-specs\"><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3.5 4.5h17\"\/><path d=\"M5.5 4.5v14h13v-14\"\/><path d=\"M3.5 21.5l2-3M20.5 21.5l-2-3\"\/><\/svg><\/span>Tela de pantalla verde<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2.5 8.5h19v9h-19z\"\/><path d=\"M13 13a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0-5 0\"\/><path d=\"M5.5 11.5h4\"\/><path d=\"M5.5 17.5v2M18.5 17.5v2\"\/><\/svg><\/span>Proyector 4K<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.5 4.5l6 2v13l-6-2z\"\/><path d=\"M19.5 4.5l-6 2v13l6-2z\"\/><\/svg><\/span>3 V-flats<\/dt><\/div><div><dt><span class=\"cc-intro-specs__icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5.5 2.5h13v8h-13z\"\/><path d=\"M12 10.5v2.5\"\/><path d=\"M4.5 13h15\"\/><path d=\"M6.5 13v5.5M17.5 13v5.5\"\/><path d=\"M6.5 16h11\"\/><path d=\"M5.5 20a1 1 0 1 0 2 0a1 1 0 1 0-2 0M16.5 20a1 1 0 1 0 2 0a1 1 0 1 0-2 0\"\/><\/svg><\/span>Carrito digital con monitor para tethering<\/dt><\/div><\/dl><\/div><\/details><\/div>\n<\/div>\n<\/section>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_7 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--rel\" id=\"reviews\"><div class=\"et_pb_row_7 et_pb_row et_block_row\"><div class=\"et_pb_column_7 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_7 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight\" data-screen-label=\"reviews\" aria-labelledby=\"reviews-title\">\n<div class=\"container-bk reveal\">\n<h2 class=\"bk-h2\" id=\"reviews-title\">300+ rese\u00f1as de 5 estrellas<\/h2>\n<p><\/p>\n<!-- HOME renders this proof as Google review cards in a Trustindex-style slider:\n     white cards, Google mark, star row, reviewer name\/source, and horizontal controls.\n     The page-system content contract still supplies real review figures through ;\n     this component owns only the card\/carousel shell and behavior.\n     Item shape from content.py: <figure class=\"rev\"><blockquote>Review<\/blockquote><figcaption>Name<span>Source<\/span><\/figcaption><\/figure>. -->\n<div class=\"rev-grid\" data-reviews-carousel>\n<button type=\"button\" aria-label=\"Previous review\">\u2039<\/button>\n<div role=\"list\" tabindex=\"0\" aria-label=\"Customer reviews\"><\/div>\n<button type=\"button\" aria-label=\"Next review\">\u203a<\/button>\n<\/div>\n<div class=\"cc-live-feed cc-live-feed--reviews\"><link data-noptimize=\"1\" data-no-optimize=\"1\" data-no-minify=\"1\" data-no-defer=\"1\" rel=\"stylesheet\" href=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/trustindex-google-widget.css?1789261151\" media=\"all\"><pre class=\"ti-widget\"><div style=\"opacity: 0;height: 0 !important;overflow: hidden !important\" data-css-url=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/trustindex-google-widget.css?1789261151\" class=\" ti-widget  ti-goog ti-no-profile-img ti-disable-font ti-review-text-mode-readmore ti-text-align-left\" data-no-translation=\"true\" data-time-locale=\"%d %s ago|today|day|days|week|weeks|month|months|year|years\" data-plugin-version=\"14.2\" data-layout-id=\"4\" data-layout-category=\"slider\" data-set-id=\"luxury-fame\" data-pid=\"wp-widget\" data-language=\"en\" data-close-locale=\"Close\" data-review-target-width=\"300\" data-css-version=\"2\" data-reply-by-locale=\"Owner&apos;s reply\" data-only-rating-locale=\"This user only left a rating.\" data-pager-autoplay-timeout=\"6\"> <div class=\"ti-widget-container ti-col-3\"> <div class=\"ti-reviews-container\"> <div class=\"ti-controls\"> <div class=\"ti-next\" aria-label=\"Next review\" role=\"button\" tabindex=\"0\"><\/div> <div class=\"ti-prev\" aria-label=\"Previous review\" role=\"button\" tabindex=\"0\"><\/div> <\/div> <div class=\"ti-reviews-container-wrapper\">  <div data-empty=\"0\" data-time=\"1791158400\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> melanie macias <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->I had a beautiful experience at CC studios!!! My photographer was Nicole and she was amazing!! She made me feel really comfortable and gave me great posing advice for my birthday pictures to come out exceptional. Definitely will come back in the future!!!<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790985600\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Rosber Angel <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->The studio is super clean, organized, and has an amazing cozy atmosphere that makes clients feel right at home. The lighting, layout, and overall space made the sessions run smoothly from start to finish.&#010;Highly recommend Creative Canvas \u2014 great experience and I\u2019ll definitely be booking again!<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790985600\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Melany C Garcia Rosell <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->Loved the studio and their energy!<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790899200\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Becca <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->I had such a wonderful experience at CC Photo Studio for the Content Strategy 101 Workshop with The 1% Girls! The ambiance was beautiful, the space was so welcoming, and the lighting was absolutely amazing. Everything came together to create such a great experience. I would highly recommend Creative Canvas to anyone looking for a beautiful studio with an amazing atmosphere! \u2728<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790899200\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Prisha Daryani <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->This is such a beautiful space! I attended a workshop here by The 1% Girls, got amazing photos taken, and definitely want to visit again.<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790899200\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Michelle Garcia <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->What a gorgeous studio! This was my first time visiting a studio of this kind and I absolutely loved it. The attention to detail was beautiful and I loved the variety of different sets available. 10\/10 and would love to come back and make content.<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790899200\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Livan Mesa <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->Awesome place, has everything you need, super quiet and beautiful, Nicole was awesome and super pro, I\u2019m really looking forward for my next shoot here.<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790726400\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Brittney Delgado <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->Had such a good session at CC Studio they have everything you need and more!!!<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790726400\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Charles Timoneda <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->Great studio! Plenty of space and a lot of background options<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <div data-empty=\"0\" data-time=\"1790121600\" class=\"ti-review-item source-Google ti-image-layout-thumbnail\" data-id=\"cfcd208495d565ef66e7dff9f98764da\" data-language=\"\"> <div class=\"ti-inner\"> <div class=\"ti-review-header\"> <div class=\"ti-platform-icon ti-with-tooltip\"> <span class=\"ti-tooltip\">Posted on Google<\/span> <img decoding=\"async\" class=\"skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/icon.svg\" alt=\"Google\" width=\"20\" height=\"20\" loading=\"lazy\" \/> <\/div>  <div class=\"ti-profile-details\"> <div class=\"ti-name\"> Anne-Katrin Meling <\/div> <div class=\"ti-date\"><\/div> <\/div> <\/div> <span class=\"ti-stars\"><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 1\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 2\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 3\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 4\" width=\"17\" height=\"17\" loading=\"lazy\" \/><img decoding=\"async\" class=\"ti-star skip-lazy\" src=\"https:\/\/cdn.trustindex.io\/assets\/platform\/Google\/star\/f.svg\" alt=\"Google star 5\" width=\"17\" height=\"17\" loading=\"lazy\" \/><\/span> <div class=\"ti-review-text-container ti-review-content\"><!-- R-CONTENT -->I had a fantastic experience at Creative Canvas Photo Studio Miami! The studio is beautifully set up, and I especially loved the variety of props available \u2014 they made it so easy to create different looks and bring the shoot to life.&#010;&#010;The lighting setup was also extremely professional and made a huge difference in the quality of the photos. Everything felt well thought out, clean, and ready to use, which made the entire experience very smooth and enjoyable.&#010;&#010;I would absolutely recommend this studio to anyone looking for a professional, versatile, and well-equipped space for a photoshoot in Miami. I\u2019d happily book here again!<!-- R-CONTENT --><\/div> <span class=\"ti-read-more\" data-container=\".ti-review-content\" data-collapse-text=\"Hide\" data-open-text=\"Read more\"><\/span> <\/div> <\/div>  <\/div> <div class=\"ti-controls-line\"> <div class=\"dot\"><\/div> <\/div> <\/div>    <\/div> <\/div> <\/pre><pre class=\"ti-hidden-markup\" hidden style=\"display: none\"><script>\n(function () { if (window.tiLoaderFallback) { return; } window.tiLoaderFallback = true; function tiLoadLoader() { if (window.TrustindexWidget || document.querySelector('script[src*=\"https:\/\/cdn.trustindex.io\/loader.js\"]')) { return; } let script = document.createElement(\"script\"); script.async = true; script.src = \"https:\/\/cdn.trustindex.io\/loader.js\"; script.setAttribute(\"data-ccm-injected\", \"1\"); document.head.appendChild(script); } if (\"loading\" === document.readyState) { document.addEventListener(\"DOMContentLoaded\", tiLoadLoader); } else { tiLoadLoader(); } })();\n<\/script>\n<\/pre><\/div>\n<\/div>\n<\/section>\n<script>(function () {\n  var script = document.currentScript;\n  var section = script && script.previousElementSibling;\n  function showPopulatedLiveWidget() {\n    var liveWidget = section && section.querySelector('.cc-live-feed--reviews .ti-widget[data-trustindex-widget]');\n    if (!liveWidget || !liveWidget.querySelector('.ti-review-item')) return false;\n    if (liveWidget.style.getPropertyValue('opacity') !== '1')\n      liveWidget.style.setProperty('opacity', '1', 'important');\n    if (liveWidget.style.getPropertyValue('height') !== 'auto')\n      liveWidget.style.setProperty('height', 'auto', 'important');\n    if (liveWidget.style.getPropertyValue('overflow') !== 'visible')\n      liveWidget.style.setProperty('overflow', 'visible', 'important');\n    liveWidget.classList.add('cc-live-feed--ready');\n    return true;\n  }\n  var liveWidgetReady = showPopulatedLiveWidget();\n  if (section && window.MutationObserver) {\n    new MutationObserver(showPopulatedLiveWidget).observe(section, {\n      childList: true, subtree: true, attributes: true, attributeFilter: ['style']\n    });\n  }\n  if (!liveWidgetReady) {\n    var liveWidgetAttempts = 0;\n    var liveWidgetTimer = window.setInterval(function () {\n      liveWidgetAttempts += 1;\n      if (showPopulatedLiveWidget() || liveWidgetAttempts >= 40)\n        window.clearInterval(liveWidgetTimer);\n    }, 250);\n  }\n  var root = section && section.querySelector('[data-reviews-carousel]');\n  if (!root || root.hasAttribute('data-reviews-ready')) return;\n  root.setAttribute('data-reviews-ready', '');\n\n  var track = root.querySelector('[role=\"list\"]');\n  var prev = root.querySelector('button[aria-label=\"Previous review\"]');\n  var next = root.querySelector('button[aria-label=\"Next review\"]');\n  if (!track || !prev || !next) return;\n  if (!track.querySelector('.rev')) { root.hidden = true; return; }\n\n  var reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n  var scrollBehavior = reducedMotion ? 'auto' : 'smooth';\n  var lang = (document.documentElement.getAttribute('lang') || '').toLowerCase();\n  var isSpanish = lang.indexOf('es') === 0;\n  var labels = isSpanish\n    ? { more: 'Leer m\u00e1s', less: 'Mostrar menos', carousel: 'Rese\u00f1as de clientes', previous: 'Rese\u00f1a anterior', next: 'Siguiente rese\u00f1a' }\n    : { more: 'Read more', less: 'Show less', carousel: 'Customer reviews', previous: 'Previous review', next: 'Next review' };\n  track.setAttribute('aria-label', labels.carousel);\n  prev.setAttribute('aria-label', labels.previous);\n  next.setAttribute('aria-label', labels.next);\n\n  function amount() {\n    var card = track.querySelector('.rev');\n    return card ? card.getBoundingClientRect().width + 18 : track.clientWidth;\n  }\n\n  function update() {\n    var max = track.scrollWidth - track.clientWidth - 2;\n    root.toggleAttribute('data-reviews-overflow', max > 2);\n    prev.disabled = track.scrollLeft <= 2;\n    next.disabled = track.scrollLeft >= max;\n  }\n\n  function prepareReviewText() {\n    root.querySelectorAll('.rev blockquote').forEach(function (quote, index) {\n      if (quote.hasAttribute('data-review-ready')) return;\n      quote.setAttribute('data-review-ready', '');\n      quote.setAttribute('data-review-collapsed', 'true');\n      if (!quote.id) quote.id = 'cc-review-quote-' + index + '-' + Math.random().toString(36).slice(2, 8);\n\n      window.requestAnimationFrame(function () {\n        if (quote.scrollHeight <= quote.clientHeight + 1) {\n          quote.removeAttribute('data-review-collapsed');\n          return;\n        }\n\n        var button = document.createElement('button');\n        button.type = 'button';\n        button.setAttribute('data-review-toggle', '');\n        button.setAttribute('aria-controls', quote.id);\n        button.setAttribute('aria-expanded', 'false');\n        button.textContent = labels.more;\n        button.addEventListener('click', function () {\n          var expanded = button.getAttribute('aria-expanded') === 'true';\n          button.setAttribute('aria-expanded', expanded ? 'false' : 'true');\n          quote.setAttribute('data-review-collapsed', expanded ? 'true' : 'false');\n          button.textContent = expanded ? labels.more : labels.less;\n          update();\n        });\n        quote.insertAdjacentElement('afterend', button);\n      });\n    });\n  }\n\n  prev.addEventListener('click', function () { track.scrollBy({ left: -amount(), behavior: scrollBehavior }); });\n  next.addEventListener('click', function () { track.scrollBy({ left: amount(), behavior: scrollBehavior }); });\n  track.addEventListener('scroll', update, { passive: true });\n  track.addEventListener('keydown', function (event) {\n    if (event.key === 'ArrowLeft') { event.preventDefault(); track.scrollBy({ left: -amount(), behavior: scrollBehavior }); }\n    if (event.key === 'ArrowRight') { event.preventDefault(); track.scrollBy({ left: amount(), behavior: scrollBehavior }); }\n  });\n  prepareReviewText();\n  new ResizeObserver(update).observe(track);\n  update();\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_8 et_pb_section et_section_regular et_block_section bk-gap-t--rel bk-gap-b--std\" id=\"press\"><div class=\"et_pb_row_8 et_pb_row et_block_row\"><div class=\"et_pb_column_8 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_8 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight\" data-screen-label=\"press\">\n<div class=\"reveal\" style=\"text-align:center;width:100%;max-width:100%\">\n<div class=\"ccp-press\">\n<div class=\"ccp-marquee\">\n<!-- logo shape: <a class=\"ccp-logo\" href=\"https:\/\/outlet.example\/story\" target=\"_blank\" rel=\"noopener\"><img src=\"...\" alt=\"Outlet Name\" style=\"height:44px\" loading=\"eager\" decoding=\"async\"><\/a>, or <span class=\"ccp-logo ccp-badge\"><img src=\"...\" alt=\"Award Name\" style=\"height:54px\" loading=\"eager\" decoding=\"async\"><\/span> for a non-link award badge; the full sequence must appear TWICE back-to-back for the marquee's seamless loop, with the second copy's links carrying aria-hidden=\"true\" tabindex=\"-1\" -->\n<div class=\"ccp-track\"><a class=\"ccp-logo\" href=\"https:\/\/voyagemia.com\/interview\/hidden-gems-meet-blanca-diaz-of-creative-canvas-studios-miami\/\" target=\"_blank\" rel=\"noopener\"><img width=\"588\" height=\"120\" style=\"height:44px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/voyagemia-featured-creative-canvas-photo-studio-miami.webp\" alt=\"VoyageMIA\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/www.youtube.com\/watch?v=QpxzctZ4bmU&amp;list=RDQpxzctZ4bmU\" target=\"_blank\" rel=\"noopener\"><img width=\"120\" height=\"120\" style=\"height:54px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/rick-ross-creative-canvas-photo-studio-miami.webp\" alt=\"Rick Ross\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"square\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/boldjourney.com\/meet-blanca-diaz\/\" target=\"_blank\" rel=\"noopener\"><img width=\"276\" height=\"120\" style=\"height:44px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/bold-journey-featured-creative-canvas-photo-studio-miami.webp\" alt=\"Bold Journey\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/miamiwire.com\/creative-canvas-studios-great-photo-studio-in-miami\/\" target=\"_blank\" rel=\"noopener\"><img width=\"720\" height=\"120\" style=\"height:38px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/miami-wire-featured-creative-canvas-photo-studio-miami.webp\" alt=\"Miami Wire\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/canvasrebel.com\/meet-blanca-diaz\/\" target=\"_blank\" rel=\"noopener\"><img width=\"1129\" height=\"120\" style=\"height:24px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/canvasrebel-featured-creative-canvas-photo-studio-miami.webp\" alt=\"CanvasRebel\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><span class=\"ccp-logo ccp-badge\"><img width=\"120\" height=\"120\" style=\"height:54px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/peerspace-open-door-awards-2025-winner-cc-studios-miami.webp\" alt=\"Peerspace Open Door Awards 2025 Winner\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"square\"><\/span><a class=\"ccp-logo\" href=\"https:\/\/shoutoutmiami.com\/meet-blanca-diaz-studio-owner-board-certified-behavior-analyst\/\" target=\"_blank\" rel=\"noopener\"><img width=\"895\" height=\"120\" style=\"height:31px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/shoutout-miami-featured-creative-canvas-photo-studio-miami.webp\" alt=\"ShoutOut Miami\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/voyagemia.com\/interview\/hidden-gems-meet-blanca-diaz-of-creative-canvas-studios-miami\/\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"588\" height=\"120\" style=\"height:44px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/voyagemia-featured-creative-canvas-photo-studio-miami.webp\" alt=\"VoyageMIA\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/www.youtube.com\/watch?v=QpxzctZ4bmU&amp;list=RDQpxzctZ4bmU\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"120\" height=\"120\" style=\"height:54px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/rick-ross-creative-canvas-photo-studio-miami.webp\" alt=\"Rick Ross\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"square\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/boldjourney.com\/meet-blanca-diaz\/\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"276\" height=\"120\" style=\"height:44px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/bold-journey-featured-creative-canvas-photo-studio-miami.webp\" alt=\"Bold Journey\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/miamiwire.com\/creative-canvas-studios-great-photo-studio-in-miami\/\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"720\" height=\"120\" style=\"height:38px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/miami-wire-featured-creative-canvas-photo-studio-miami.webp\" alt=\"Miami Wire\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><a class=\"ccp-logo\" href=\"https:\/\/canvasrebel.com\/meet-blanca-diaz\/\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"1129\" height=\"120\" style=\"height:24px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/canvasrebel-featured-creative-canvas-photo-studio-miami.webp\" alt=\"CanvasRebel\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><span class=\"ccp-logo ccp-badge\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"120\" height=\"120\" style=\"height:54px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/peerspace-open-door-awards-2025-winner-cc-studios-miami.webp\" alt=\"Peerspace Open Door Awards 2025 Winner\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"square\"><\/span><a class=\"ccp-logo\" href=\"https:\/\/shoutoutmiami.com\/meet-blanca-diaz-studio-owner-board-certified-behavior-analyst\/\" target=\"_blank\" rel=\"noopener\" aria-hidden=\"true\" tabindex=\"-1\"><img width=\"895\" height=\"120\" style=\"height:31px;object-position:50% 50%\" src=\"https:\/\/a4c9adde.delivery.rocketcdn.me\/wp-content\/uploads\/2026\/09\/shoutout-miami-featured-creative-canvas-photo-studio-miami.webp\" alt=\"ShoutOut Miami\" loading=\"eager\" decoding=\"async\" data-frame-orientation=\"landscape\"><\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<script>(function () {\n  var strip = document.currentScript.previousElementSibling.querySelector('.ccp-marquee');\n  strip.setAttribute('data-cc-press-ready', '');\n  strip.addEventListener('focusin', function (event) {\n    if (event.target.matches('a.ccp-logo')) {\n      event.target.scrollIntoView({block: 'nearest', inline: 'nearest', behavior: 'instant'});\n    }\n  });\n  strip.addEventListener('focusout', function () {\n    window.requestAnimationFrame(function () {\n      if (!strip.contains(document.activeElement)) strip.scrollLeft = 0;\n    });\n  });\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_9 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--std\" id=\"faq\"><div class=\"et_pb_row_9 et_pb_row et_block_row\"><div class=\"et_pb_column_9 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_9 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight\" data-screen-label=\"faq\" aria-labelledby=\"faq-title\">\n<div class=\"container-bk reveal\">\n<h2 class=\"bk-h2\" id=\"faq-title\">Preguntas frecuentes<\/h2>\n<!-- item shape: <div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">Question?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">Answer.<\/div><\/div><\/div>, one per question; exactly one item's button should ship aria-expanded=\"true\" so it opens by default -->\n<div class=\"faq\"><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"true\">\u00bfCu\u00e1nto cuesta rentar el estudio de fotograf\u00eda y video por hora?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">Nuestro estudio cuesta $110 la hora entre semana y $130 el fin de semana, con m\u00ednimo de una hora. Una sesi\u00f3n de cuatro horas cuesta $410 entre semana o $500 el fin de semana. <a href=\"\/es\/precios\/\">Ver todas las tarifas<\/a>.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPueden producir el video por nosotros?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. Podemos hacer desde solo el espacio hasta un paquete de producci\u00f3n completo. <a href=\"\/es\/contacto\/\">Cont\u00e1ctanos<\/a> para hablar de tu proyecto y te lo cotizamos.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfQu\u00e9 incluye la renta del estudio para video?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">Todo el estudio privado, los ocho sets, las luces y el grip de la lista de arriba, la tela de pantalla verde, la estaci\u00f3n de maquillaje, Wi-Fi, A\/C, snacks y espacio para 15 personas.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPodemos usar humo o niebla?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed, se permiten el humo y la niebla.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPuedo oscurecer las ventanas?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. Las siete ventanas tienen cortinas blackout.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfEl montaje cuenta dentro de mi tiempo reservado?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. El montaje y el desmontaje se hacen dentro de tu tiempo reservado, as\u00ed que reserva horas suficientes para ambos.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfD\u00f3nde estacionamos y c\u00f3mo cargamos el equipo?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">El estacionamiento es gratis en el lugar, tambi\u00e9n para vans y camiones. El estudio est\u00e1 en el segundo piso, solo con escaleras y sin elevador, as\u00ed que planea tu equipo.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPuedo grabar audio limpio aqu\u00ed?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">Cont\u00e1ctanos antes de reservar para hablar de tus requisitos de grabaci\u00f3n y audio.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfCu\u00e1ntas personas puedo traer?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">Se incluyen hasta 15 personas, entre equipo y talento. Preg\u00fantanos antes de reservar si necesitas m\u00e1s; los grupos m\u00e1s grandes pueden tener un cargo adicional.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPuedo ver el estudio antes?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. Los tours en persona son gratis con cita: escribe o llama al 786-869-6010. O <a href=\"\/es\/tour-virtual\/\">haz el tour virtual<\/a>.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfHay \u00e1rea de maquillaje, Wi-Fi y A\/C?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. Hay estaci\u00f3n de maquillaje, Wi-Fi y A\/C, y los snacks est\u00e1n incluidos.<\/div><\/div><\/div><div class=\"faq-item\"><button class=\"faq-q\" type=\"button\" aria-expanded=\"false\">\u00bfPodemos grabar temprano en la ma\u00f1ana o tarde en la noche?<span class=\"faq-icon\"><\/span><\/button><div class=\"faq-a\"><div class=\"faq-a__in\">S\u00ed. El acceso reservado est\u00e1 disponible 24\/7, a la misma tarifa por hora.<\/div><\/div><\/div><\/div>\n<\/div>\n<\/section>\n<script>(function () {\n  var root = document.currentScript.previousElementSibling.querySelector('.faq');\n  if (!root || root.hasAttribute('data-cc-disclosure-ready')) { return; }\n  var nextId = 0;\n  root.querySelectorAll('.faq-item').forEach(function (item) {\n    var btn = item.querySelector('.faq-q');\n    var panel = item.querySelector('.faq-a');\n    \/\/ Preserve legacy content whose initial state lives on the item wrapper.\n    if (item.hasAttribute('aria-expanded')) {\n      btn.setAttribute('aria-expanded', item.getAttribute('aria-expanded'));\n      item.removeAttribute('aria-expanded');\n    }\n    \/\/ Generate associations per instance, including when authored IDs collide.\n    var id;\n    do { id = 'cc-faq-panel-' + nextId++; } while (document.getElementById(id));\n    panel.id = id;\n    btn.setAttribute('aria-controls', id);\n    function setOpen(open) {\n      btn.setAttribute('aria-expanded', open ? 'true' : 'false');\n      panel.inert = !open;\n      panel.setAttribute('aria-hidden', open ? 'false' : 'true');\n      panel.style.maxHeight = open ? panel.scrollHeight + 'px' : '0px';\n    }\n    setOpen(btn.getAttribute('aria-expanded') === 'true');\n    btn.addEventListener('click', function () {\n      setOpen(btn.getAttribute('aria-expanded') !== 'true');\n    });\n  });\n  root.setAttribute('data-cc-disclosure-ready', '');\n  function ccFaqFit() {\n    root.querySelectorAll('.faq-q[aria-expanded=\"true\"]').forEach(function (btn) {\n      var panel = btn.closest('.faq-item').querySelector('.faq-a');\n      panel.style.maxHeight = panel.scrollHeight + 'px';\n    });\n  }\n  window.addEventListener('load', ccFaqFit);\n  window.addEventListener('resize', ccFaqFit);\n  if (document.fonts && document.fonts.ready) {\n    document.fonts.ready.then(ccFaqFit);\n  }\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_10 et_pb_section et_section_regular et_block_section bk-gap-t--std bk-gap-b--none bk-section--flush-footer\" id=\"map\"><div class=\"et_pb_row_10 et_pb_row et_block_row\"><div class=\"et_pb_column_10 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_10 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><section class=\"bk-section bk-section--tight\" data-screen-label=\"map\">\n<div class=\"container-bk reveal\">\n<h2 class=\"bk-h2 hm-map__title\"><\/h2>\n<p class=\"bk-lead\"><\/p>\n<div class=\"hm-map\">\n<!-- CC Studios Miami en Google Maps is the iframe's accessible name and must never be empty: an untitled iframe is a WCAG 4.1.2 failure and it is the only thing a screen reader announces here. No width\/height attributes -- .hm-map__frame sets both, and attribute values fight the clamp. -->\n<iframe class=\"hm-map__frame\" src=\"https:\/\/www.google.com\/maps\/embed?pb=!1m18!1m12!1m3!1d3594.3138405577283!2d-80.32018612469999!3d25.727133010032915!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x88d9b979af7cdd23%3A0xef2b81d3827d34e9!2sCreative%20Canvas%20Photo%20Studio%20Miami!5e0!3m2!1sen!2sus!4v1777941529875!5m2!1sen!2sus\" title=\"CC Studios Miami en Google Maps\" loading=\"lazy\" referrerpolicy=\"no-referrer-when-downgrade\" allowfullscreen><\/iframe>\n<\/div>\n<\/div>\n<\/section>\n<\/div><\/div><\/div><\/div><\/div><div class=\"et_pb_section_11 et_pb_section et_section_regular et_block_section\" id=\"sticky\"><div class=\"et_pb_row_11 et_pb_row et_block_row\"><div class=\"et_pb_column_11 et_pb_column et_pb_column_4_4 et-last-child et_block_column et_pb_css_mix_blend_mode_passthrough\"><div class=\"et_pb_code_11 et_pb_code et_pb_module\"><div class=\"et_pb_code_inner\"><div class=\"stickybar\" id=\"bk-stickybar\" inert aria-hidden=\"true\">\n<div class=\"stickybar__surface\">\n<div class=\"stickybar__price\"><b>Estudio desde $110\/hora<\/b><\/div>\n<a class=\"btn--bar\" href=\"\/es\/reservar\/?book=rental&amp;entry=video&amp;cta=sticky-rental#book\">Reservar<\/a>\n<\/div>\n<\/div>\n<script>(function () {\n  var script = document.currentScript;\n  var bar = script && script.previousElementSibling;\n  if (!bar) return;\n  var hostSection = bar.closest('.bk-sticky--after-gallery-opening');\n  var afterGalleryOpening = !!hostSection;\n  var page = document.getElementById('page-container');\n  if (page && page.parentNode) page.parentNode.insertBefore(bar, page);\n  else document.body.insertBefore(bar, document.body.firstChild);\n  var hero = document.querySelector('.hm-hero, .cc-hero-plain');\n  var past = hero ? false : (window.scrollY || window.pageYOffset) > 380;\n  var nearBottom = false;\n  var shown = null;\n  var scheduled = false;\n\n  function apply() {\n    var visible = (past && !nearBottom) || bar.contains(document.activeElement);\n    if (visible === shown) return;\n    shown = visible;\n    bar.inert = !visible;\n    bar.setAttribute('aria-hidden', String(!visible));\n    bar.classList.toggle('show', visible);\n  }\n\n  function measureFallback() {\n    scheduled = false;\n    if (afterGalleryOpening) {\n      var figures = Array.prototype.slice.call(\n        document.querySelectorAll('#space .gal-grid > figure:not([hidden])')\n      );\n      var rowBottoms = [];\n      figures.forEach(function (figure) {\n        var bottom = Math.round(figure.getBoundingClientRect().bottom);\n        if (!rowBottoms.some(function (value) { return Math.abs(value - bottom) <= 2; }))\n          rowBottoms.push(bottom);\n      });\n      rowBottoms.sort(function (a, b) { return a - b; });\n      past = rowBottoms.length ? rowBottoms[Math.min(1, rowBottoms.length - 1)] <= 80 : false;\n    } else {\n      past = hero ? hero.getBoundingClientRect().bottom <= 80 :\n        (window.scrollY || window.pageYOffset) > 380;\n    }\n    var viewportHeight = window.visualViewport ? window.visualViewport.height : window.innerHeight;\n    nearBottom = viewportHeight + (window.scrollY || window.pageYOffset) >\n      document.documentElement.scrollHeight - 130;\n    apply();\n  }\n\n  function scheduleFallback() {\n    if (scheduled) return;\n    scheduled = true;\n    requestAnimationFrame(measureFallback);\n  }\n\n  function watchPageEnd() {\n    var footer = document.querySelector('footer, .et-l--footer');\n    if (footer) {\n      new IntersectionObserver(function (entries) {\n        nearBottom = entries[0].isIntersecting;\n        apply();\n      }, { threshold: 0 }).observe(footer);\n    } else {\n      window.addEventListener('scroll', scheduleFallback, { passive: true });\n      window.addEventListener('resize', scheduleFallback);\n      if (window.visualViewport) window.visualViewport.addEventListener('resize', scheduleFallback);\n      scheduleFallback();\n    }\n  }\n\n  function watchGalleryOpening() {\n    window.addEventListener('scroll', scheduleFallback, { passive: true });\n    window.addEventListener('resize', scheduleFallback);\n    if (window.visualViewport) window.visualViewport.addEventListener('resize', scheduleFallback);\n    var gallery = document.getElementById('space');\n    if (gallery) gallery.addEventListener('click', scheduleFallback);\n    scheduleFallback();\n  }\n\n  if ('IntersectionObserver' in window) {\n    if (afterGalleryOpening) {\n      if (document.readyState === 'loading')\n        document.addEventListener('DOMContentLoaded', watchGalleryOpening, { once: true });\n      else watchGalleryOpening();\n    } else if (hero) {\n      new IntersectionObserver(function (entries) {\n        var entry = entries[0];\n        past = !entry.isIntersecting && entry.boundingClientRect.bottom <= 80;\n        apply();\n      }, { rootMargin: '-80px 0px 0px 0px', threshold: 0 }).observe(hero);\n    }\n    if (document.readyState === 'loading')\n      document.addEventListener('DOMContentLoaded', watchPageEnd, { once: true });\n    else watchPageEnd();\n  } else {\n    window.addEventListener('scroll', scheduleFallback, { passive: true });\n    window.addEventListener('resize', scheduleFallback);\n    if (window.visualViewport) window.visualViewport.addEventListener('resize', scheduleFallback);\n    scheduleFallback();\n  }\n  document.addEventListener('DOMContentLoaded', apply);\n  bar.addEventListener('focusout', function () { requestAnimationFrame(apply); });\n  apply();\n})();<\/script>\n<\/div><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":235371522,"featured_media":194038,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_custom_body_class":"","_custom_post_class":"","cybocfi_hide_featured_image":"","_wpcom_ai_launchpad_about_page":false,"_wpcom_ai_launchpad_gallery_page":false,"_wpcom_ai_launchpad_contact_page":false,"_wpcom_ai_launchpad_events_page":false,"_wpcom_ai_launchpad_video_page":false,"_wpcom_ai_launchpad_portfolio_piece":false,"_jetpack_hide_featured_image":false,"_jetpack_featured_image_duplicate_dismissed":0,"footnotes":""},"class_list":["post-193545","page","type-page","status-publish","has-post-thumbnail","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO Pro 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"google-site-verification\" content=\"fnBC2bCyO0UwWiaR8e9kOi8fjzV96W_0wT17f00tc1s\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO Pro (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Creative Canvas Photo Studio Miami | Photo Studio in Miami with Multi-Sets and Cyclorama Wall\" \/>\n\t\t<meta property=\"og:type\" content=\"website\" \/>\n\t\t<meta property=\"og:title\" content=\"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110\" \/>\n\t\t<meta property=\"og:description\" content=\"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t\t<meta property=\"og:image:height\" content=\"1067\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:site\" content=\"@ccstudiosmiami\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.\" \/>\n\t\t<meta name=\"twitter:creator\" content=\"@ccstudiosmiami\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#listItem\",\"name\":\"Renta de Estudio de Video en Miami\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#listItem\",\"position\":2,\"name\":\"Renta de Estudio de Video en Miami\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#listItem\",\"name\":\"Home\"}}]},{\"@context\":\"https:\\\/\\\/schema.org\",\"@type\":\"FAQPage\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#faqpage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"\\u00bfCu\\u00e1nto cuesta rentar el estudio de fotograf\\u00eda y video por hora?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Nuestro estudio cuesta $110 la hora entre semana y $130 el fin de semana, con m\\u00ednimo de una hora. Una sesi\\u00f3n de cuatro horas cuesta $410 entre semana o $500 el fin de semana. Ver todas las tarifas .\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPueden producir el video por nosotros?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. Podemos hacer desde solo el espacio hasta un paquete de producci\\u00f3n completo. Cont\\u00e1ctanos para hablar de tu proyecto y te lo cotizamos.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfQu\\u00e9 incluye la renta del estudio para video?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Todo el estudio privado, los ocho sets, las luces y el grip de la lista de arriba, la tela de pantalla verde, la estaci\\u00f3n de maquillaje, Wi-Fi, A\\\/C, snacks y espacio para 15 personas.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPodemos usar humo o niebla?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed, se permiten el humo y la niebla.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPuedo oscurecer las ventanas?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. Las siete ventanas tienen cortinas blackout.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfEl montaje cuenta dentro de mi tiempo reservado?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. El montaje y el desmontaje se hacen dentro de tu tiempo reservado, as\\u00ed que reserva horas suficientes para ambos.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfD\\u00f3nde estacionamos y c\\u00f3mo cargamos el equipo?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"El estacionamiento es gratis en el lugar, tambi\\u00e9n para vans y camiones. El estudio est\\u00e1 en el segundo piso, solo con escaleras y sin elevador, as\\u00ed que planea tu equipo.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPuedo grabar audio limpio aqu\\u00ed?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Cont\\u00e1ctanos antes de reservar para hablar de tus requisitos de grabaci\\u00f3n y audio.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfCu\\u00e1ntas personas puedo traer?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Se incluyen hasta 15 personas, entre equipo y talento. Preg\\u00fantanos antes de reservar si necesitas m\\u00e1s; los grupos m\\u00e1s grandes pueden tener un cargo adicional.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPuedo ver el estudio antes?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. Los tours en persona son gratis con cita: escribe o llama al 786-869-6010. O haz el tour virtual .\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfHay \\u00e1rea de maquillaje, Wi-Fi y A\\\/C?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. Hay estaci\\u00f3n de maquillaje, Wi-Fi y A\\\/C, y los snacks est\\u00e1n incluidos.\"}},{\"@type\":\"Question\",\"name\":\"\\u00bfPodemos grabar temprano en la ma\\u00f1ana o tarde en la noche?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"S\\u00ed. El acceso reservado est\\u00e1 disponible 24\\\/7, a la misma tarifa por hora.\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#organization\",\"name\":\"Creative Canvas Photo Studio Miami\",\"description\":\"Creative Canvas Photo Studio Miami (CC Studios) is a fully private 3,000 sq ft photo, video and content studio in Glenvar Heights, Miami. Every booking is the whole studio: eight sets in total, including a 25 by 20 ft white cyclorama wall, plus professional lighting, props, a hair and makeup station and free on-site parking. Studio rental is $110 an hour on weekdays and $130 on weekends, photoshoots start at $350, and the studio can be booked 24\\\/7 by appointment.\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/\",\"email\":\"bookings@ccstudiosmiami.com\",\"telephone\":\"+17868696010\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/cc-logo-transparent.png\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#organizationLogo\",\"width\":332,\"height\":237,\"caption\":\"#image_title\"},\"image\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#organizationLogo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/ccstudiosmiami\\\/\",\"https:\\\/\\\/x.com\\\/ccstudiosmiami\",\"https:\\\/\\\/www.instagram.com\\\/ccstudiosmia\\\/\",\"https:\\\/\\\/www.tiktok.com\\\/@ccstudiosmiami\",\"https:\\\/\\\/www.pinterest.com\\\/ccstudiosmia\\\/\",\"https:\\\/\\\/www.youtube.com\\\/@ccstudiosmiami\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/ccstudiosmiami\",\"https:\\\/\\\/www.tumblr.com\\\/creativecanvasphotostudiomiami\",\"https:\\\/\\\/www.yelp.com\\\/biz\\\/creative-canvas-studios-miami\",\"https:\\\/\\\/www.peerspace.com\\\/pages\\\/listings\\\/64b2dc9970383c000e881cdf\",\"https:\\\/\\\/www.google.com\\\/maps?cid=17234011144490661097\"]},{\"@type\":\"Service\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#service\",\"name\":\"Estudio de fotograf\\u00eda y video por hora\",\"serviceType\":\"Renta de estudio de video\",\"description\":\"Estudio de fotograf\\u00eda y video privado de 3,000 pies\\u00b2 en Miami con ocho sets, incluido el ciclorama blanco de 25\\u2032 \\u00d7 20\\u2032, luces de video y grip incluidos, espacio para 15 personas y acceso 24\\\/7. Renta todo el estudio desde $110 la hora entre semana y $130 el fin de semana, m\\u00ednimo una hora.\",\"image\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/white-cyclorama-wall-photography-lighting-miami-studio-1.webp\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/\",\"provider\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"},\"areaServed\":[{\"@type\":\"City\",\"name\":\"Miami\",\"containedInPlace\":{\"@type\":\"AdministrativeArea\",\"name\":\"Miami-Dade County, Florida\"}}],\"offers\":{\"@type\":\"Offer\",\"priceCurrency\":\"USD\",\"price\":\"110\",\"description\":\"Renta del estudio desde $110 la hora entre semana y $130 el fin de semana, m\\u00ednimo una hora.\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/precios\\\/\"}},{\"@type\":\"Service\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#video-production\",\"name\":\"Producci\\u00f3n de video en Miami\",\"serviceType\":\"Producci\\u00f3n de video\",\"description\":\"Desde solo el espacio hasta un paquete de producci\\u00f3n completo, cotizado por proyecto. Cont\\u00e1ctanos para hablar de tu proyecto.\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/contacto\\\/\",\"provider\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"},\"areaServed\":[{\"@type\":\"City\",\"name\":\"Miami\",\"containedInPlace\":{\"@type\":\"AdministrativeArea\",\"name\":\"Miami-Dade County, Florida\"}}]},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-1\",\"name\":\"Video musical ft. Rick Ross, grabado en CC Studios Miami\",\"description\":\"Video musical grabado en nuestro estudio de fotograf\\u00eda y video: Finesse2tymes y Rick Ross frente a la pared de botellas doradas\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-music-video-rick-ross-gold-bottle-wall-cover.jpg\",\"embedUrl\":\"https:\\\/\\\/www.youtube.com\\\/embed\\\/QpxzctZ4bmU\",\"url\":\"https:\\\/\\\/www.youtube.com\\\/watch?v=QpxzctZ4bmU\",\"uploadDate\":\"2024-01-18T21:00:11-08:00\"},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-2\",\"name\":\"Comercial, grabado en CC Studios Miami\",\"description\":\"Comercial grabado en nuestro estudio de fotograf\\u00eda y video: tres presentadores de traje en el ciclorama blanco, con un close-up del producto\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-commercial-white-cyclorama-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-commercial-white-cyclorama.mp4\",\"uploadDate\":\"2026-10-07\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"}},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-3\",\"name\":\"Testimonio de marca, grabado en CC Studios Miami\",\"description\":\"Testimonio de marca grabado en el set de arcos de nuestro estudio de fotograf\\u00eda y video, con una demostraci\\u00f3n del producto en el sof\\u00e1\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-brand-testimonial-arch-set-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-brand-testimonial-arch-set.mp4\",\"uploadDate\":\"2026-10-07\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"}},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-4\",\"name\":\"Entrevista, grabado en CC Studios Miami\",\"description\":\"Entrevista grabada en el ciclorama blanco de nuestro estudio de fotograf\\u00eda y video: dos personas en sillones de piel\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-studio-miami-sit-down-interview-cyclorama-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-studio-miami-sit-down-interview-cyclorama.mp4\",\"uploadDate\":\"2026-10-07\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"}},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-5\",\"name\":\"Recap de evento, grabado en CC Studios Miami\",\"description\":\"Recap de evento grabado en nuestro estudio de fotograf\\u00eda y video: un set de cena, un perchero, una sesi\\u00f3n grupal y un set de pastel\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-event-recap-styled-set-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-event-recap-styled-set.mp4\",\"uploadDate\":\"2026-10-07\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"}},{\"@type\":\"VideoObject\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#clip-6\",\"name\":\"Reel del estudio, grabado en CC Studios Miami\",\"description\":\"Reel de nuestro estudio de fotograf\\u00eda y video: entrevistas, testimonios, detr\\u00e1s de c\\u00e1maras y campa\\u00f1as\",\"thumbnailUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-studio-reel-cover.jpg\",\"contentUrl\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/video-production-studio-miami-studio-reel.mp4\",\"uploadDate\":\"2026-10-07\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/#localbusiness\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#webpage\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/\",\"name\":\"Estudio de Fotograf\\u00eda y Video | Renta por Hora desde $110\",\"description\":\"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\\u00f1as.\",\"inLanguage\":\"es-ES\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#breadcrumblist\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/ccstudios-downtown-miami-content-creation-studio.jpg\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#mainImage\",\"width\":1600,\"height\":1067,\"caption\":\"#image_title\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/renta-de-estudio-de-video-miami\\\/#mainImage\"},\"datePublished\":\"2026-06-22T12:32:07-04:00\",\"dateModified\":\"2026-10-07T20:57:56-04:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#website\",\"url\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/\",\"name\":\"Creative Canvas Photo Studio Miami\",\"alternateName\":\"CC Studios\",\"description\":\"Photo Studio in Miami with Multi-Sets and Cyclorama Wall\",\"inLanguage\":\"es-ES\",\"publisher\":{\"@id\":\"https:\\\/\\\/ccstudiosmiami.com\\\/es\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO Pro -->\r\n\t\t<title>Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110<\/title>\n\n","aioseo_head_json":{"title":"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110","description":"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.","canonical_url":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"fnBC2bCyO0UwWiaR8e9kOi8fjzV96W_0wT17f00tc1s","miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/ccstudiosmiami.com\/es\/#listItem","position":1,"name":"Home","item":"https:\/\/ccstudiosmiami.com\/es\/","nextItem":{"@type":"ListItem","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#listItem","name":"Renta de Estudio de Video en Miami"}},{"@type":"ListItem","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#listItem","position":2,"name":"Renta de Estudio de Video en Miami","previousItem":{"@type":"ListItem","@id":"https:\/\/ccstudiosmiami.com\/es\/#listItem","name":"Home"}}]},{"@context":"https:\/\/schema.org","@type":"FAQPage","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#faqpage","mainEntity":[{"@type":"Question","name":"\u00bfCu\u00e1nto cuesta rentar el estudio de fotograf\u00eda y video por hora?","acceptedAnswer":{"@type":"Answer","text":"Nuestro estudio cuesta $110 la hora entre semana y $130 el fin de semana, con m\u00ednimo de una hora. Una sesi\u00f3n de cuatro horas cuesta $410 entre semana o $500 el fin de semana. Ver todas las tarifas ."}},{"@type":"Question","name":"\u00bfPueden producir el video por nosotros?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. Podemos hacer desde solo el espacio hasta un paquete de producci\u00f3n completo. Cont\u00e1ctanos para hablar de tu proyecto y te lo cotizamos."}},{"@type":"Question","name":"\u00bfQu\u00e9 incluye la renta del estudio para video?","acceptedAnswer":{"@type":"Answer","text":"Todo el estudio privado, los ocho sets, las luces y el grip de la lista de arriba, la tela de pantalla verde, la estaci\u00f3n de maquillaje, Wi-Fi, A\/C, snacks y espacio para 15 personas."}},{"@type":"Question","name":"\u00bfPodemos usar humo o niebla?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed, se permiten el humo y la niebla."}},{"@type":"Question","name":"\u00bfPuedo oscurecer las ventanas?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. Las siete ventanas tienen cortinas blackout."}},{"@type":"Question","name":"\u00bfEl montaje cuenta dentro de mi tiempo reservado?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. El montaje y el desmontaje se hacen dentro de tu tiempo reservado, as\u00ed que reserva horas suficientes para ambos."}},{"@type":"Question","name":"\u00bfD\u00f3nde estacionamos y c\u00f3mo cargamos el equipo?","acceptedAnswer":{"@type":"Answer","text":"El estacionamiento es gratis en el lugar, tambi\u00e9n para vans y camiones. El estudio est\u00e1 en el segundo piso, solo con escaleras y sin elevador, as\u00ed que planea tu equipo."}},{"@type":"Question","name":"\u00bfPuedo grabar audio limpio aqu\u00ed?","acceptedAnswer":{"@type":"Answer","text":"Cont\u00e1ctanos antes de reservar para hablar de tus requisitos de grabaci\u00f3n y audio."}},{"@type":"Question","name":"\u00bfCu\u00e1ntas personas puedo traer?","acceptedAnswer":{"@type":"Answer","text":"Se incluyen hasta 15 personas, entre equipo y talento. Preg\u00fantanos antes de reservar si necesitas m\u00e1s; los grupos m\u00e1s grandes pueden tener un cargo adicional."}},{"@type":"Question","name":"\u00bfPuedo ver el estudio antes?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. Los tours en persona son gratis con cita: escribe o llama al 786-869-6010. O haz el tour virtual ."}},{"@type":"Question","name":"\u00bfHay \u00e1rea de maquillaje, Wi-Fi y A\/C?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. Hay estaci\u00f3n de maquillaje, Wi-Fi y A\/C, y los snacks est\u00e1n incluidos."}},{"@type":"Question","name":"\u00bfPodemos grabar temprano en la ma\u00f1ana o tarde en la noche?","acceptedAnswer":{"@type":"Answer","text":"S\u00ed. El acceso reservado est\u00e1 disponible 24\/7, a la misma tarifa por hora."}}]},{"@type":"Organization","@id":"https:\/\/ccstudiosmiami.com\/es\/#organization","name":"Creative Canvas Photo Studio Miami","description":"Creative Canvas Photo Studio Miami (CC Studios) is a fully private 3,000 sq ft photo, video and content studio in Glenvar Heights, Miami. Every booking is the whole studio: eight sets in total, including a 25 by 20 ft white cyclorama wall, plus professional lighting, props, a hair and makeup station and free on-site parking. Studio rental is $110 an hour on weekdays and $130 on weekends, photoshoots start at $350, and the studio can be booked 24\/7 by appointment.","url":"https:\/\/ccstudiosmiami.com\/es\/","email":"bookings@ccstudiosmiami.com","telephone":"+17868696010","logo":{"@type":"ImageObject","url":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/cc-logo-transparent.png","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#organizationLogo","width":332,"height":237,"caption":"#image_title"},"image":{"@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#organizationLogo"},"sameAs":["https:\/\/www.facebook.com\/ccstudiosmiami\/","https:\/\/x.com\/ccstudiosmiami","https:\/\/www.instagram.com\/ccstudiosmia\/","https:\/\/www.tiktok.com\/@ccstudiosmiami","https:\/\/www.pinterest.com\/ccstudiosmia\/","https:\/\/www.youtube.com\/@ccstudiosmiami","https:\/\/www.linkedin.com\/company\/ccstudiosmiami","https:\/\/www.tumblr.com\/creativecanvasphotostudiomiami","https:\/\/www.yelp.com\/biz\/creative-canvas-studios-miami","https:\/\/www.peerspace.com\/pages\/listings\/64b2dc9970383c000e881cdf","https:\/\/www.google.com\/maps?cid=17234011144490661097"]},{"@type":"Service","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#service","name":"Estudio de fotograf\u00eda y video por hora","serviceType":"Renta de estudio de video","description":"Estudio de fotograf\u00eda y video privado de 3,000 pies\u00b2 en Miami con ocho sets, incluido el ciclorama blanco de 25\u2032 \u00d7 20\u2032, luces de video y grip incluidos, espacio para 15 personas y acceso 24\/7. Renta todo el estudio desde $110 la hora entre semana y $130 el fin de semana, m\u00ednimo una hora.","image":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/white-cyclorama-wall-photography-lighting-miami-studio-1.webp","url":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/","provider":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"},"areaServed":[{"@type":"City","name":"Miami","containedInPlace":{"@type":"AdministrativeArea","name":"Miami-Dade County, Florida"}}],"offers":{"@type":"Offer","priceCurrency":"USD","price":"110","description":"Renta del estudio desde $110 la hora entre semana y $130 el fin de semana, m\u00ednimo una hora.","url":"https:\/\/ccstudiosmiami.com\/es\/precios\/"}},{"@type":"Service","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#video-production","name":"Producci\u00f3n de video en Miami","serviceType":"Producci\u00f3n de video","description":"Desde solo el espacio hasta un paquete de producci\u00f3n completo, cotizado por proyecto. Cont\u00e1ctanos para hablar de tu proyecto.","url":"https:\/\/ccstudiosmiami.com\/es\/contacto\/","provider":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"},"areaServed":[{"@type":"City","name":"Miami","containedInPlace":{"@type":"AdministrativeArea","name":"Miami-Dade County, Florida"}}]},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-1","name":"Video musical ft. Rick Ross, grabado en CC Studios Miami","description":"Video musical grabado en nuestro estudio de fotograf\u00eda y video: Finesse2tymes y Rick Ross frente a la pared de botellas doradas","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-music-video-rick-ross-gold-bottle-wall-cover.jpg","embedUrl":"https:\/\/www.youtube.com\/embed\/QpxzctZ4bmU","url":"https:\/\/www.youtube.com\/watch?v=QpxzctZ4bmU","uploadDate":"2024-01-18T21:00:11-08:00"},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-2","name":"Comercial, grabado en CC Studios Miami","description":"Comercial grabado en nuestro estudio de fotograf\u00eda y video: tres presentadores de traje en el ciclorama blanco, con un close-up del producto","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama-cover.jpg","contentUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama.mp4","uploadDate":"2026-10-07","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"}},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-3","name":"Testimonio de marca, grabado en CC Studios Miami","description":"Testimonio de marca grabado en el set de arcos de nuestro estudio de fotograf\u00eda y video, con una demostraci\u00f3n del producto en el sof\u00e1","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set-cover.jpg","contentUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set.mp4","uploadDate":"2026-10-07","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"}},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-4","name":"Entrevista, grabado en CC Studios Miami","description":"Entrevista grabada en el ciclorama blanco de nuestro estudio de fotograf\u00eda y video: dos personas en sillones de piel","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama-cover.jpg","contentUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama.mp4","uploadDate":"2026-10-07","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"}},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-5","name":"Recap de evento, grabado en CC Studios Miami","description":"Recap de evento grabado en nuestro estudio de fotograf\u00eda y video: un set de cena, un perchero, una sesi\u00f3n grupal y un set de pastel","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set-cover.jpg","contentUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set.mp4","uploadDate":"2026-10-07","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"}},{"@type":"VideoObject","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-6","name":"Reel del estudio, grabado en CC Studios Miami","description":"Reel de nuestro estudio de fotograf\u00eda y video: entrevistas, testimonios, detr\u00e1s de c\u00e1maras y campa\u00f1as","thumbnailUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel-cover.jpg","contentUrl":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel.mp4","uploadDate":"2026-10-07","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/#localbusiness"}},{"@type":"WebPage","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#webpage","url":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/","name":"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110","description":"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.","inLanguage":"es-ES","isPartOf":{"@id":"https:\/\/ccstudiosmiami.com\/es\/#website"},"breadcrumb":{"@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#breadcrumblist"},"image":{"@type":"ImageObject","url":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg","@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#mainImage","width":1600,"height":1067,"caption":"#image_title"},"primaryImageOfPage":{"@id":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#mainImage"},"datePublished":"2026-06-22T12:32:07-04:00","dateModified":"2026-10-07T20:57:56-04:00"},{"@type":"WebSite","@id":"https:\/\/ccstudiosmiami.com\/es\/#website","url":"https:\/\/ccstudiosmiami.com\/es\/","name":"Creative Canvas Photo Studio Miami","alternateName":"CC Studios","description":"Photo Studio in Miami with Multi-Sets and Cyclorama Wall","inLanguage":"es-ES","publisher":{"@id":"https:\/\/ccstudiosmiami.com\/es\/#organization"}}]},"og:locale":"es_ES","og:site_name":"Creative Canvas Photo Studio Miami | Photo Studio in Miami with Multi-Sets and Cyclorama Wall","og:type":"website","og:title":"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110","og:description":"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.","og:url":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/","og:image":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg","og:image:secure_url":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg","og:image:width":1600,"og:image:height":1067,"twitter:card":"summary_large_image","twitter:site":"@ccstudiosmiami","twitter:title":"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110","twitter:description":"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.","twitter:creator":"@ccstudiosmiami","twitter:image":"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/ccstudios-downtown-miami-content-creation-studio.jpg"},"aioseo_meta_data":{"post_id":"193545","title":"Estudio de Fotograf\u00eda y Video | Renta por Hora desde $110","description":"Graba tu video musical, comercial o entrevista en nuestro estudio de fotograf\u00eda y video: 8 sets, luces y parqueo gratis. Desde $110 por hora. 300+ rese\u00f1as.","keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[{"id":"#aioseo-custom-es-video-faqs","custom":true,"graphName":"FAQs","schema":"{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#faqpage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"\u00bfCu\u00e1nto cuesta rentar el estudio de fotograf\u00eda y video por hora?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Nuestro estudio cuesta $110 la hora entre semana y $130 el fin de semana, con m\u00ednimo de una hora. Una sesi\u00f3n de cuatro horas cuesta $410 entre semana o $500 el fin de semana. Ver todas las tarifas .\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPueden producir el video por nosotros?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. Podemos hacer desde solo el espacio hasta un paquete de producci\u00f3n completo. Cont\u00e1ctanos para hablar de tu proyecto y te lo cotizamos.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfQu\u00e9 incluye la renta del estudio para video?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Todo el estudio privado, los ocho sets, las luces y el grip de la lista de arriba, la tela de pantalla verde, la estaci\u00f3n de maquillaje, Wi-Fi, A\/C, snacks y espacio para 15 personas.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPodemos usar humo o niebla?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed, se permiten el humo y la niebla.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPuedo oscurecer las ventanas?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. Las siete ventanas tienen cortinas blackout.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfEl montaje cuenta dentro de mi tiempo reservado?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. El montaje y el desmontaje se hacen dentro de tu tiempo reservado, as\u00ed que reserva horas suficientes para ambos.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfD\u00f3nde estacionamos y c\u00f3mo cargamos el equipo?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"El estacionamiento es gratis en el lugar, tambi\u00e9n para vans y camiones. El estudio est\u00e1 en el segundo piso, solo con escaleras y sin elevador, as\u00ed que planea tu equipo.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPuedo grabar audio limpio aqu\u00ed?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Cont\u00e1ctanos antes de reservar para hablar de tus requisitos de grabaci\u00f3n y audio.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfCu\u00e1ntas personas puedo traer?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Se incluyen hasta 15 personas, entre equipo y talento. Preg\u00fantanos antes de reservar si necesitas m\u00e1s; los grupos m\u00e1s grandes pueden tener un cargo adicional.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPuedo ver el estudio antes?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. Los tours en persona son gratis con cita: escribe o llama al 786-869-6010. O haz el tour virtual .\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfHay \u00e1rea de maquillaje, Wi-Fi y A\/C?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. Hay estaci\u00f3n de maquillaje, Wi-Fi y A\/C, y los snacks est\u00e1n incluidos.\"}}, {\"@type\": \"Question\", \"name\": \"\u00bfPodemos grabar temprano en la ma\u00f1ana o tarde en la noche?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"S\u00ed. El acceso reservado est\u00e1 disponible 24\/7, a la misma tarifa por hora.\"}}]}"},{"id":"#aioseo-custom-es-renta-de-estudio-de-video-miami-service","custom":true,"graphName":"Service","schema":"{\"@context\": \"https:\/\/schema.org\", \"@graph\": [{\"@type\": \"Service\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#service\", \"name\": \"Estudio de fotograf\u00eda y video por hora\", \"serviceType\": \"Renta de estudio de video\", \"description\": \"Estudio de fotograf\u00eda y video privado de 3,000 pies\u00b2 en Miami con ocho sets, incluido el ciclorama blanco de 25\u2032 \u00d7 20\u2032, luces de video y grip incluidos, espacio para 15 personas y acceso 24\/7. Renta todo el estudio desde $110 la hora entre semana y $130 el fin de semana, m\u00ednimo una hora.\", \"image\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/06\/white-cyclorama-wall-photography-lighting-miami-studio-1.webp\", \"url\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/\", \"provider\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}, \"areaServed\": [{\"@type\": \"City\", \"name\": \"Miami\", \"containedInPlace\": {\"@type\": \"AdministrativeArea\", \"name\": \"Miami-Dade County, Florida\"}}], \"offers\": {\"@type\": \"Offer\", \"priceCurrency\": \"USD\", \"price\": \"110\", \"description\": \"Renta del estudio desde $110 la hora entre semana y $130 el fin de semana, m\u00ednimo una hora.\", \"url\": \"https:\/\/ccstudiosmiami.com\/es\/precios\/\"}}, {\"@type\": \"Service\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#video-production\", \"name\": \"Producci\u00f3n de video en Miami\", \"serviceType\": \"Producci\u00f3n de video\", \"description\": \"Desde solo el espacio hasta un paquete de producci\u00f3n completo, cotizado por proyecto. Cont\u00e1ctanos para hablar de tu proyecto.\", \"url\": \"https:\/\/ccstudiosmiami.com\/es\/contacto\/\", \"provider\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}, \"areaServed\": [{\"@type\": \"City\", \"name\": \"Miami\", \"containedInPlace\": {\"@type\": \"AdministrativeArea\", \"name\": \"Miami-Dade County, Florida\"}}]}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-1\", \"name\": \"Video musical ft. Rick Ross, grabado en CC Studios Miami\", \"description\": \"Video musical grabado en nuestro estudio de fotograf\u00eda y video: Finesse2tymes y Rick Ross frente a la pared de botellas doradas\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-music-video-rick-ross-gold-bottle-wall-cover.jpg\", \"embedUrl\": \"https:\/\/www.youtube.com\/embed\/QpxzctZ4bmU\", \"url\": \"https:\/\/www.youtube.com\/watch?v=QpxzctZ4bmU\", \"uploadDate\": \"2024-01-18T21:00:11-08:00\"}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-2\", \"name\": \"Comercial, grabado en CC Studios Miami\", \"description\": \"Comercial grabado en nuestro estudio de fotograf\u00eda y video: tres presentadores de traje en el ciclorama blanco, con un close-up del producto\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama-cover.jpg\", \"contentUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-commercial-white-cyclorama.mp4\", \"uploadDate\": \"2026-10-07\", \"publisher\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-3\", \"name\": \"Testimonio de marca, grabado en CC Studios Miami\", \"description\": \"Testimonio de marca grabado en el set de arcos de nuestro estudio de fotograf\u00eda y video, con una demostraci\u00f3n del producto en el sof\u00e1\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set-cover.jpg\", \"contentUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-brand-testimonial-arch-set.mp4\", \"uploadDate\": \"2026-10-07\", \"publisher\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-4\", \"name\": \"Entrevista, grabado en CC Studios Miami\", \"description\": \"Entrevista grabada en el ciclorama blanco de nuestro estudio de fotograf\u00eda y video: dos personas en sillones de piel\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama-cover.jpg\", \"contentUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-studio-miami-sit-down-interview-cyclorama.mp4\", \"uploadDate\": \"2026-10-07\", \"publisher\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-5\", \"name\": \"Recap de evento, grabado en CC Studios Miami\", \"description\": \"Recap de evento grabado en nuestro estudio de fotograf\u00eda y video: un set de cena, un perchero, una sesi\u00f3n grupal y un set de pastel\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set-cover.jpg\", \"contentUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-event-recap-styled-set.mp4\", \"uploadDate\": \"2026-10-07\", \"publisher\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}}, {\"@type\": \"VideoObject\", \"@id\": \"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/#clip-6\", \"name\": \"Reel del estudio, grabado en CC Studios Miami\", \"description\": \"Reel de nuestro estudio de fotograf\u00eda y video: entrevistas, testimonios, detr\u00e1s de c\u00e1maras y campa\u00f1as\", \"thumbnailUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel-cover.jpg\", \"contentUrl\": \"https:\/\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/10\/video-production-studio-miami-studio-reel.mp4\", \"uploadDate\": \"2026-10-07\", \"publisher\": {\"@id\": \"https:\/\/ccstudiosmiami.com\/#localbusiness\"}}]}"}],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"WebPage","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":true,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":0,"frequency":"default","local_seo":null,"seo_analyzer_scan_date":"2026-10-08 00:58:48","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":"0","open_ai":null,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":[],"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-08-02 14:05:30","updated":"2026-10-08 00:58:48","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/ccstudiosmiami.com\/es\/\" title=\"Home\">Home<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">|<\/span><span class=\"aioseo-breadcrumb\">\n\tRenta de Estudio de Video en Miami\n<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/ccstudiosmiami.com\/es\/"},{"label":"Renta de Estudio de Video en Miami","link":"https:\/\/ccstudiosmiami.com\/es\/renta-de-estudio-de-video-miami\/"}],"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":194822,"url":"https:\/\/ccstudiosmiami.com\/es\/fotografia-boudoir-estudio-miami\/","url_meta":{"origin":193545,"position":0},"title":"Fotograf\u00eda Boudoir en un Estudio Privado de Miami","author":"Blanca Diaz","date":"18 de agosto de 2026","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"Alquiler de estudio de v\u00eddeo y podcast en Miami cerca del centro con espacio privado de 3.000 pies cuadrados, fondos de papel continuo, estaci\u00f3n de maquillaje y configuraci\u00f3n completa de producci\u00f3n.","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":193539,"url":"https:\/\/ccstudiosmiami.com\/es\/renta-de-ciclorama-miami\/","url_meta":{"origin":193545,"position":1},"title":"Renta de Ciclorama en Miami","author":"Blanca Diaz","date":"24 de mayo de 2026","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"Cyclorama wall for productions. Perfect setup in Miami photo studio","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/05\/rental-studio-for-videography-miami-scaled.jpeg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":193459,"url":"https:\/\/ccstudiosmiami.com\/es\/estudio-de-fotos-coral-gables\/","url_meta":{"origin":193545,"position":2},"title":"Estudio de Fotos Cerca de Coral Gables","author":"Blanca Diaz","date":"17 de agosto de 2025","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"Alquiler de estudio de v\u00eddeo y podcast en Miami cerca del centro con espacio privado de 3.000 pies cuadrados, fondos de papel continuo, estaci\u00f3n de maquillaje y configuraci\u00f3n completa de producci\u00f3n.","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/07\/downtown-miami-video-podcast-studio-rental-scaled.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":194819,"url":"https:\/\/ccstudiosmiami.com\/es\/estudio-de-fotografia-de-producto-miami\/","url_meta":{"origin":193545,"position":3},"title":"Estudio de Fotograf\u00eda de Producto en Miami","author":"Blanca Diaz","date":"23 de agosto de 2026","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/11\/top-photo-studio-miami.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/11\/top-photo-studio-miami.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/11\/top-photo-studio-miami.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/11\/top-photo-studio-miami.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2025\/11\/top-photo-studio-miami.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":193491,"url":"https:\/\/ccstudiosmiami.com\/es\/mejor-estudio-de-fotos-miami\/","url_meta":{"origin":193545,"position":4},"title":"Estudio Privado de Fotos en Miami","author":"Blanca Diaz","date":"6 de febrero de 2026","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/01\/miami-photo-studio-gallery-display-prop-set.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":193549,"url":"https:\/\/ccstudiosmiami.com\/es\/estudio-de-podcast-miami\/","url_meta":{"origin":193545,"position":5},"title":"Estudio de Podcast en Miami","author":"Blanca Diaz","date":"17 de junio de 2026","format":false,"excerpt":"","rel":"","context":"Entrada similar","block_context":{"text":"Entrada similar","link":""},"img":{"alt_text":"Miami portrait studio for couples and family photos with private space, natural light zones, and clean backdrops.","src":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/ccstudiosmiami.com\/wp-content\/uploads\/2026\/03\/miami-beach-photo-studio-rental-near-south-beach.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/pages\/193545","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/users\/235371522"}],"replies":[{"embeddable":true,"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/comments?post=193545"}],"version-history":[{"count":28,"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/pages\/193545\/revisions"}],"predecessor-version":[{"id":196933,"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/pages\/193545\/revisions\/196933"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/media\/194038"}],"wp:attachment":[{"href":"https:\/\/ccstudiosmiami.com\/es\/wp-json\/wp\/v2\/media?parent=193545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}