Bed & Breakfast Inn Landing
A warm, rustic single-page landing for a countryside Bed & Breakfast featuring cozy room cards, a breakfast menu section, a host story block, and an interactive reservation widget with nights calculator, room picker, breakfast toggle, and form toast feedback.
MCP
程式碼
/* ── Theme: Rosehip Inn — cream + sage + terracotta ── */
:root {
--cream: #f5f0e6;
--cream-2: #ede5d4;
--cream-3: #faf7f0;
--sage: #5a7a5a;
--sage-2: #7a9e7a;
--sage-light: #a8c4a8;
--sage-pale: #e8f0e8;
--terra: #c4633a;
--terra-light: #e08060;
--terra-pale: #f5e8e0;
--ink: #2a1e14;
--ink-2: #4a3828;
--muted: #6e5e4e;
--warm-line: rgba(90, 60, 30, 0.12);
--warm-line-strong: rgba(90, 60, 30, 0.22);
--success: #4a7752;
--danger: #b03c1e;
--font-hand: "Caveat", cursive;
--font-serif: "Lora", Georgia, serif;
--r-sm: 6px;
--r-md: 12px;
--r-lg: 20px;
--r-pill: 999px;
--shadow-1: 0 2px 10px rgba(42, 30, 20, 0.08), 0 1px 2px rgba(42, 30, 20, 0.06);
--shadow-2: 0 12px 40px rgba(42, 30, 20, 0.16);
--shadow-3: 0 24px 64px rgba(42, 30, 20, 0.22);
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-serif);
background: var(--cream);
color: var(--ink);
-webkit-font-smoothing: antialiased;
}
a {
text-decoration: none;
}
/* ── Nav ── */
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
align-items: center;
gap: 20px;
padding: 14px 40px;
background: var(--cream);
border-bottom: 1px solid var(--warm-line);
box-shadow: 0 2px 16px rgba(42, 30, 20, 0.1);
transform: translateY(-100%);
transition: transform 0.3s ease;
}
.nav.visible {
transform: translateY(0);
}
.brand {
display: flex;
align-items: center;
gap: 8px;
color: var(--ink);
}
.brand-mark {
font-size: 1.5rem;
line-height: 1;
}
.brand-name {
font-family: var(--font-hand);
font-size: 1.4rem;
font-weight: 700;
color: var(--terra);
}
.nav-links {
display: flex;
gap: 26px;
margin-left: auto;
}
.nav-links a {
font-family: var(--font-serif);
color: var(--muted);
font-size: 0.88rem;
font-weight: 600;
transition: color 0.15s;
}
.nav-links a:hover {
color: var(--terra);
}
.nav-cta {
background: var(--terra);
color: #fff;
font-family: var(--font-serif);
font-weight: 700;
font-size: 0.86rem;
padding: 9px 18px;
border-radius: var(--r-pill);
transition: background 0.15s;
}
.nav-cta:hover {
background: var(--terra-light);
}
/* ── Hero ── */
.hero {
position: relative;
min-height: 100vh;
padding: 80px 40px 60px;
display: flex;
align-items: center;
overflow: hidden;
background: var(--cream-2);
}
.hero-bg {
position: absolute;
inset: 0;
background: radial-gradient(ellipse 70% 80% at 0% 0%, rgba(90, 122, 90, 0.2), transparent 55%),
radial-gradient(ellipse 60% 70% at 100% 100%, rgba(196, 99, 58, 0.15), transparent 55%),
linear-gradient(145deg, #ede5d4 0%, #f5f0e6 60%, #e8f0e8 100%);
pointer-events: none;
}
/* Decorative watercolour blob */
.hero-bg::after {
content: "";
position: absolute;
width: 400px;
height: 400px;
right: 5%;
top: 8%;
border-radius: 55% 45% 50% 50% / 45% 55% 50% 50%;
background: linear-gradient(135deg, rgba(90, 122, 90, 0.15), rgba(196, 99, 58, 0.08));
pointer-events: none;
}
.hero-inner {
position: relative;
z-index: 2;
width: 100%;
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 400px;
gap: 56px;
align-items: center;
}
.hero-copy {
color: var(--ink);
}
.handwritten-tag {
font-family: var(--font-hand);
font-size: 1.3rem;
color: var(--sage);
font-weight: 600;
margin-bottom: 10px;
display: block;
}
.hero-copy h1 {
font-family: var(--font-serif);
font-weight: 700;
font-size: clamp(2.8rem, 6vw, 5rem);
line-height: 1.05;
letter-spacing: -0.01em;
color: var(--ink);
margin-bottom: 20px;
}
.lede {
font-size: 1.05rem;
line-height: 1.7;
color: var(--muted);
max-width: 460px;
margin-bottom: 28px;
font-style: italic;
}
.hero-perks {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.hero-perks span {
background: rgba(90, 122, 90, 0.12);
border: 1px solid rgba(90, 122, 90, 0.25);
color: var(--sage);
font-family: var(--font-serif);
font-size: 0.84rem;
font-weight: 600;
padding: 7px 14px;
border-radius: var(--r-pill);
}
/* ── Reservation widget ── */
.rwidget {
background: var(--cream-3);
border: 1.5px solid var(--warm-line-strong);
border-radius: var(--r-lg);
padding: 26px;
box-shadow: var(--shadow-3);
}
.rw-title {
font-family: var(--font-hand);
font-size: 1.4rem;
font-weight: 700;
color: var(--terra);
margin-bottom: 18px;
padding-bottom: 14px;
border-bottom: 1.5px dashed var(--warm-line-strong);
}
.rw-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 12px;
}
.rw-field {
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 12px;
}
.rw-row .rw-field {
margin-bottom: 0;
}
.rw-field label {
font-family: var(--font-hand);
font-size: 0.88rem;
font-weight: 600;
color: var(--muted);
letter-spacing: 0.04em;
}
.rw-field input[type="date"],
.rw-field select {
font-family: var(--font-serif);
font-size: 0.92rem;
font-weight: 600;
color: var(--ink);
background: var(--cream);
border: 1.5px solid var(--warm-line-strong);
border-radius: var(--r-sm);
padding: 9px 10px;
outline: none;
width: 100%;
transition: border-color 0.15s;
}
.rw-field input[type="date"]:focus,
.rw-field select:focus {
border-color: var(--terra);
}
.gest-row {
display: flex;
align-items: center;
gap: 10px;
background: var(--cream);
border: 1.5px solid var(--warm-line-strong);
border-radius: var(--r-sm);
padding: 7px 10px;
}
.gest-row span {
font-family: var(--font-serif);
font-weight: 700;
font-size: 1.05rem;
color: var(--ink);
min-width: 20px;
text-align: center;
}
.gest-btn {
width: 28px;
height: 28px;
border-radius: var(--r-pill);
border: 1.5px solid var(--warm-line-strong);
background: var(--cream-3);
color: var(--ink);
font-size: 1.2rem;
line-height: 1;
cursor: pointer;
display: grid;
place-items: center;
transition: background 0.12s;
}
.gest-btn:hover:not(:disabled) {
background: var(--terra-pale);
border-color: var(--terra);
}
.gest-btn:disabled {
opacity: 0.3;
cursor: default;
}
.nights-col {
justify-content: flex-start;
}
.nights-num {
font-family: var(--font-hand);
font-weight: 700;
font-size: 2.2rem;
color: var(--terra);
line-height: 1;
padding-top: 2px;
}
.bkfast-toggle {
display: flex;
align-items: center;
gap: 10px;
font-family: var(--font-serif);
font-size: 0.84rem;
color: var(--ink-2);
cursor: pointer;
margin-bottom: 14px;
user-select: none;
line-height: 1.4;
}
.bkfast-toggle input {
display: none;
}
.bk-track {
width: 40px;
height: 22px;
flex-shrink: 0;
border-radius: var(--r-pill);
background: var(--sage-light);
position: relative;
transition: background 0.2s;
}
.bk-track::after {
content: "";
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
top: 3px;
left: 3px;
transition: transform 0.2s;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.bkfast-toggle input:checked ~ .bk-track {
background: var(--sage);
}
.bkfast-toggle input:checked ~ .bk-track::after {
transform: translateX(18px);
}
.rw-total {
background: var(--sage-pale);
border: 1px solid rgba(90, 122, 90, 0.25);
border-radius: var(--r-sm);
padding: 10px 14px;
font-size: 0.9rem;
font-weight: 600;
color: var(--muted);
margin-bottom: 14px;
min-height: 42px;
display: flex;
align-items: center;
font-family: var(--font-serif);
}
.rw-total strong {
color: var(--ink);
}
.rw-total.error {
background: var(--terra-pale);
border-color: rgba(196, 99, 58, 0.3);
color: var(--danger);
}
.rw-btn {
width: 100%;
background: var(--terra);
color: #fff;
border: none;
font-family: var(--font-serif);
font-weight: 700;
font-size: 0.96rem;
padding: 14px;
border-radius: var(--r-md);
cursor: pointer;
letter-spacing: 0.02em;
transition: background 0.15s, transform 0.1s;
}
.rw-btn:hover {
background: var(--terra-light);
transform: translateY(-1px);
}
/* ── Section headings ── */
.sec-hd {
text-align: center;
margin-bottom: 44px;
}
.sec-hd h2 {
font-family: var(--font-serif);
font-weight: 700;
font-size: clamp(2rem, 3.5vw, 2.8rem);
color: var(--ink);
letter-spacing: -0.01em;
margin-top: 4px;
}
.handwritten-eyebrow {
font-family: var(--font-hand);
font-size: 1.2rem;
font-weight: 600;
color: var(--sage);
display: block;
}
.handwritten-eyebrow--cream {
color: rgba(255, 255, 255, 0.7);
}
.handwritten-eyebrow--terra {
color: var(--terra-light);
}
/* ── Rooms ── */
.rooms {
max-width: 1100px;
margin: 80px auto;
padding: 0 40px;
}
.room-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.rc {
background: var(--cream-3);
border: 1.5px solid var(--warm-line);
border-radius: var(--r-lg);
overflow: hidden;
box-shadow: var(--shadow-1);
position: relative;
transition: transform 0.2s, box-shadow 0.2s;
}
.rc:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-2);
}
.rc--pick {
border-color: var(--terra);
box-shadow: 0 0 0 1px var(--terra), var(--shadow-1);
}
.rc-ribbon {
position: absolute;
top: 14px;
right: -4px;
background: var(--terra);
color: #fff;
font-family: var(--font-hand);
font-size: 0.88rem;
font-weight: 700;
padding: 4px 14px 4px 10px;
z-index: 2;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 8% 50%);
}
.rc-img {
height: 195px;
position: relative;
}
.rc-img--rose {
background: linear-gradient(135deg, #c4736a 0%, #8a4040 60%, #5a2828 100%);
}
.rc-img--rose::after {
content: "🌹🌹";
position: absolute;
bottom: 14px;
left: 16px;
font-size: 1.6rem;
}
.rc-img--orchard {
background: linear-gradient(135deg, #6a8f50 0%, #4a6a35 60%, #2d4820 100%);
}
.rc-img--orchard::after {
content: "🍏🌿";
position: absolute;
bottom: 14px;
left: 16px;
font-size: 1.6rem;
}
.rc-img--lavender {
background: linear-gradient(135deg, #7a5a9a 0%, #5a3a78 60%, #3d2060 100%);
}
.rc-img--lavender::after {
content: "💜🌾";
position: absolute;
bottom: 14px;
left: 16px;
font-size: 1.6rem;
}
.rc-img::before {
content: "";
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 70% 20%, rgba(255, 255, 255, 0.18), transparent 60%);
}
.rc-body {
padding: 20px 22px 24px;
}
.rc-body h3 {
font-family: var(--font-serif);
font-weight: 700;
font-size: 1.3rem;
color: var(--ink);
margin-bottom: 4px;
}
.rc-detail {
font-size: 0.76rem;
color: var(--muted);
font-style: italic;
margin-bottom: 10px;
}
.rc-desc {
font-size: 0.87rem;
color: var(--ink-2);
line-height: 1.6;
margin-bottom: 14px;
}
.rc-features {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 14px;
}
.rc-features span {
background: var(--sage-pale);
border: 1px solid rgba(90, 122, 90, 0.2);
color: var(--sage);
font-family: var(--font-serif);
font-size: 0.76rem;
padding: 4px 10px;
border-radius: var(--r-pill);
}
.rc-price {
font-family: var(--font-serif);
font-size: 0.88rem;
color: var(--muted);
font-weight: 600;
border-top: 1px solid var(--warm-line);
padding-top: 12px;
}
.rc-price strong {
font-family: var(--font-serif);
font-size: 1.7rem;
font-weight: 700;
color: var(--terra);
}
/* ── Breakfast ── */
.breakfast {
background: var(--sage);
padding: 80px 40px;
}
.bk-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: 60px;
align-items: center;
}
.bk-copy h2 {
font-family: var(--font-serif);
font-weight: 700;
font-size: clamp(1.8rem, 3vw, 2.6rem);
color: #fff;
letter-spacing: -0.01em;
margin: 6px 0 14px;
}
.bk-lede {
font-style: italic;
font-size: 0.96rem;
color: rgba(255, 255, 255, 0.8);
line-height: 1.65;
max-width: 420px;
margin-bottom: 24px;
}
.bk-menu {
list-style: none;
display: flex;
flex-direction: column;
gap: 0;
}
.bk-menu li {
padding: 14px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.bk-menu li:last-child {
border-bottom: none;
}
.bk-menu strong {
display: block;
font-family: var(--font-serif);
font-size: 0.96rem;
font-weight: 700;
color: #fff;
margin-bottom: 3px;
}
.bk-menu span {
font-size: 0.82rem;
color: rgba(255, 255, 255, 0.65);
line-height: 1.5;
}
.bk-note {
margin-top: 16px;
font-style: italic;
font-size: 0.82rem;
color: rgba(255, 255, 255, 0.6);
}
.bk-visual {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.bk-plate {
width: 240px;
height: 240px;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(245, 240, 230, 0.18) 0%,
rgba(245, 240, 230, 0.06) 60%,
transparent 70%
), radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 50%);
border: 2px dashed rgba(255, 255, 255, 0.2);
display: grid;
place-items: center;
position: relative;
}
.bk-emoji {
position: absolute;
font-size: 2.8rem;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: float 4s ease-in-out infinite;
}
.bk-emoji--2 {
top: 15%;
left: 72%;
font-size: 2rem;
animation-delay: 1s;
}
.bk-emoji--3 {
top: 70%;
left: 20%;
font-size: 2rem;
animation-delay: 2s;
}
.bk-emoji--4 {
top: 75%;
left: 70%;
font-size: 1.6rem;
animation-delay: 0.5s;
}
@keyframes float {
0%,
100% {
transform: translate(-50%, -50%);
}
50% {
transform: translate(-50%, calc(-50% - 7px));
}
}
.bk-caption {
font-family: var(--font-hand);
font-size: 1.1rem;
color: rgba(255, 255, 255, 0.65);
}
/* ── Story ── */
.story {
padding: 90px 40px;
background: var(--cream-2);
}
.story-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.story-img {
height: 450px;
border-radius: var(--r-lg);
background: radial-gradient(ellipse 60% 60% at 30% 40%, rgba(90, 122, 90, 0.4), transparent 55%),
radial-gradient(ellipse 50% 50% at 80% 80%, rgba(196, 99, 58, 0.25), transparent 50%),
linear-gradient(145deg, #d4c8a0, #b8a87a);
position: relative;
overflow: hidden;
box-shadow: var(--shadow-2);
border: 1.5px solid var(--warm-line);
}
.story-img::before {
content: "🏡";
position: absolute;
font-size: 9rem;
top: 50%;
left: 50%;
transform: translate(-50%, -58%);
opacity: 0.18;
}
.story-img::after {
content: "Est. 1994 · Cotswolds";
position: absolute;
bottom: 22px;
left: 22px;
background: rgba(255, 255, 255, 0.88);
color: var(--terra);
font-family: var(--font-hand);
font-size: 0.9rem;
font-weight: 700;
padding: 7px 14px;
border-radius: var(--r-pill);
}
.story-copy .handwritten-eyebrow {
margin-bottom: 10px;
}
.story-copy h2 {
font-family: var(--font-serif);
font-weight: 700;
font-size: clamp(1.8rem, 3.2vw, 2.5rem);
color: var(--ink);
letter-spacing: -0.01em;
margin-bottom: 18px;
line-height: 1.15;
}
.story-copy p {
font-size: 0.95rem;
color: var(--muted);
line-height: 1.75;
margin-bottom: 14px;
}
.story-nums {
display: flex;
gap: 28px;
padding-top: 24px;
margin-top: 20px;
border-top: 2px dashed var(--warm-line-strong);
}
.snum strong {
display: block;
font-family: var(--font-hand);
font-size: 2.2rem;
font-weight: 700;
color: var(--terra);
line-height: 1;
}
.snum span {
font-size: 0.78rem;
color: var(--muted);
font-style: italic;
display: block;
margin-top: 2px;
}
/* ── Find us ── */
.find-us {
background: var(--ink);
padding: 80px 40px;
}
.find-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1.4fr;
gap: 56px;
align-items: center;
}
.find-info .handwritten-eyebrow {
color: var(--sage-light);
margin-bottom: 8px;
}
.find-info h2 {
font-family: var(--font-serif);
font-weight: 700;
font-size: 2rem;
color: #fff;
margin-bottom: 24px;
letter-spacing: -0.01em;
}
.hours {
list-style: none;
margin-bottom: 24px;
}
.hours li {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
font-size: 0.88rem;
}
.hours li span {
color: rgba(255, 255, 255, 0.5);
font-style: italic;
}
.hours li strong {
color: #fff;
font-weight: 600;
}
.address {
padding: 18px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: var(--r-md);
color: rgba(255, 255, 255, 0.65);
font-size: 0.88rem;
line-height: 1.7;
}
.addr-name {
font-family: var(--font-hand);
font-size: 1.1rem;
font-weight: 700;
color: #fff;
margin-bottom: 3px;
}
.map-wrap {
height: 300px;
border-radius: var(--r-lg);
background: #1c3020;
position: relative;
overflow: hidden;
box-shadow: var(--shadow-2);
}
.map-bg {
position: absolute;
inset: 0;
background-image: linear-gradient(rgba(90, 122, 90, 0.12) 1px, transparent 1px),
linear-gradient(90deg, rgba(90, 122, 90, 0.12) 1px, transparent 1px);
background-size: 44px 44px;
}
.map-dot-wrap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.map-dot-inner {
width: 14px;
height: 14px;
background: var(--terra);
border-radius: 50%;
border: 2.5px solid #fff;
position: relative;
z-index: 2;
}
.map-dot-outer {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(196, 99, 58, 0.25);
animation: pulse 2.5s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
transform: translate(-50%, -50%) scale(1);
opacity: 0.8;
}
50% {
transform: translate(-50%, -50%) scale(1.6);
opacity: 0;
}
}
.map-card {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: var(--cream-3);
border: 1px solid var(--warm-line);
border-radius: var(--r-md);
padding: 10px 18px;
text-align: center;
white-space: nowrap;
box-shadow: var(--shadow-1);
}
.map-card strong {
display: block;
font-family: var(--font-hand);
font-size: 1rem;
font-weight: 700;
color: var(--terra);
}
.map-card span {
font-size: 0.76rem;
color: var(--muted);
font-style: italic;
}
/* ── Reserve ── */
.reserve {
background: var(--terra-pale);
padding: 72px 40px;
border-top: 2px solid var(--warm-line-strong);
}
.reserve-wrap {
max-width: 960px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1.2fr;
gap: 56px;
align-items: start;
}
.reserve-copy h2 {
font-family: var(--font-serif);
font-weight: 700;
font-size: 2.6rem;
color: var(--ink);
letter-spacing: -0.02em;
margin: 6px 0 14px;
}
.reserve-copy p {
font-style: italic;
font-size: 0.95rem;
color: var(--muted);
line-height: 1.65;
}
.reserve-form {
display: flex;
flex-direction: column;
gap: 12px;
}
.reserve-form input,
.reserve-form textarea {
font-family: var(--font-serif);
font-size: 0.92rem;
color: var(--ink);
background: var(--cream-3);
border: 1.5px solid var(--warm-line-strong);
border-radius: var(--r-sm);
padding: 12px 14px;
outline: none;
resize: vertical;
transition: border-color 0.15s;
}
.reserve-form input:focus,
.reserve-form textarea:focus {
border-color: var(--terra);
}
.reserve-form button {
background: var(--terra);
color: #fff;
border: none;
font-family: var(--font-serif);
font-weight: 700;
font-size: 0.96rem;
padding: 14px;
border-radius: var(--r-md);
cursor: pointer;
letter-spacing: 0.02em;
transition: background 0.15s;
}
.reserve-form button:hover {
background: var(--terra-light);
}
/* ── Toast ── */
.toast {
position: fixed;
bottom: 26px;
left: 50%;
transform: translateX(-50%);
background: var(--ink);
color: var(--cream);
padding: 13px 26px;
border-radius: var(--r-pill);
font-family: var(--font-serif);
font-size: 0.88rem;
font-weight: 600;
box-shadow: var(--shadow-2);
z-index: 200;
border: 1.5px solid rgba(196, 99, 58, 0.4);
white-space: nowrap;
}
/* ── Responsive ── */
@media (max-width: 960px) {
.hero-inner {
grid-template-columns: 1fr;
}
.rwidget {
max-width: 480px;
}
.room-row {
grid-template-columns: 1fr;
max-width: 480px;
margin: 0 auto;
}
.bk-inner {
grid-template-columns: 1fr;
}
.bk-visual {
display: none;
}
.story-inner {
grid-template-columns: 1fr;
}
.story-img {
height: 260px;
}
.find-inner {
grid-template-columns: 1fr;
}
.reserve-wrap {
grid-template-columns: 1fr;
}
}
@media (max-width: 560px) {
.nav {
padding: 12px 20px;
}
.nav-links {
display: none;
}
.hero {
padding: 60px 20px 48px;
}
.rooms,
.story {
padding-left: 20px;
padding-right: 20px;
}
.breakfast,
.find-us,
.reserve {
padding-left: 20px;
padding-right: 20px;
}
.rw-row {
grid-template-columns: 1fr;
}
.story-nums {
flex-direction: column;
gap: 14px;
}
}// ── Toast helper ─────────────────────────────────────────────────────────────
const toast = document.getElementById("toast");
function showToast(msg) {
toast.textContent = msg;
toast.hidden = false;
clearTimeout(showToast._t);
showToast._t = setTimeout(() => (toast.hidden = true), 2200);
}
// ── Sticky nav on scroll ──────────────────────────────────────────────────────
const nav = document.getElementById("nav");
const THRESH = window.innerHeight * 0.75;
window.addEventListener(
"scroll",
() => {
nav.classList.toggle("visible", window.scrollY > THRESH);
},
{ passive: true }
);
// ── Date helpers ──────────────────────────────────────────────────────────────
function iso(d) {
return d.toISOString().slice(0, 10);
}
function addDays(date, n) {
const d = new Date(date);
d.setDate(d.getDate() + n);
return d;
}
function fmtDate(isoStr) {
return new Date(isoStr + "T00:00").toLocaleDateString("en-GB", {
weekday: "short",
day: "numeric",
month: "long",
});
}
// ── Room rates & breakfast ────────────────────────────────────────────────────
const ROOM_RATES = { rose: 95, orchard: 110, lavender: 145 };
const BK_RATE = 18; // per guest per night
// ── Reservation widget ────────────────────────────────────────────────────────
const rciEl = document.getElementById("rci");
const rcoEl = document.getElementById("rco");
const rroomEl = document.getElementById("rroom");
const gvEl = document.getElementById("gv");
const gmBtn = document.getElementById("gm");
const gpBtn = document.getElementById("gp");
const rNightsEl = document.getElementById("rNights");
const rTotalEl = document.getElementById("rTotal");
const bkEl = document.getElementById("bkfast");
// Defaults: check-in 9 Jun, check-out 12 Jun 2026
const today = new Date("2026-06-08");
const defIn = new Date("2026-06-09");
const defOut = new Date("2026-06-12");
rciEl.value = iso(defIn);
rcoEl.value = iso(defOut);
rciEl.min = iso(today);
rcoEl.min = iso(addDays(today, 1));
let gCount = 2;
function calcNights() {
if (!rciEl.value || !rcoEl.value) return 0;
const ms = new Date(rcoEl.value) - new Date(rciEl.value);
return Math.round(ms / 86400000);
}
function renderWidget() {
const n = calcNights();
const rate = ROOM_RATES[rroomEl.value] ?? 110;
const bkInc = bkEl.checked;
const bkCost = bkInc ? BK_RATE * gCount * n : 0;
const total = n * rate + bkCost;
if (n <= 0) {
rNightsEl.textContent = "—";
rTotalEl.classList.add("error");
rTotalEl.textContent = "⚠ Departure must be after arrival";
return;
}
rTotalEl.classList.remove("error");
rNightsEl.textContent = n;
const bkNote = bkInc ? ` + <em>£${bkCost} bkfast</em>` : " · no breakfast";
rTotalEl.innerHTML =
`<strong>£${total}</strong> total · ${n} night${n === 1 ? "" : "s"}` +
` · ${gCount} guest${gCount === 1 ? "" : "s"}${bkNote}`;
}
// Guest stepper
function syncGuests() {
gvEl.textContent = gCount;
gmBtn.disabled = gCount <= 1;
gpBtn.disabled = gCount >= 4;
}
gmBtn.addEventListener("click", () => {
if (gCount > 1) {
gCount--;
syncGuests();
renderWidget();
}
});
gpBtn.addEventListener("click", () => {
if (gCount < 4) {
gCount++;
syncGuests();
renderWidget();
}
});
rciEl.addEventListener("change", () => {
const inD = new Date(rciEl.value);
const minOut = iso(addDays(inD, 1));
rcoEl.min = minOut;
if (new Date(rcoEl.value) <= inD) rcoEl.value = minOut;
renderWidget();
});
rcoEl.addEventListener("change", renderWidget);
rroomEl.addEventListener("change", renderWidget);
bkEl.addEventListener("change", renderWidget);
// Widget form submit
document.getElementById("reserveWidget").addEventListener("submit", (e) => {
e.preventDefault();
const n = calcNights();
if (n <= 0) {
renderWidget();
return;
}
const room = rroomEl.options[rroomEl.selectedIndex].text.split(" —")[0];
const rate = ROOM_RATES[rroomEl.value] ?? 110;
const bkInc = bkEl.checked;
const bkCost = bkInc ? BK_RATE * gCount * n : 0;
const total = n * rate + bkCost;
const bkStr = bkInc ? " · breakfast incl." : "";
showToast(`🌹 ${room} · ${fmtDate(rciEl.value)} – ${fmtDate(rcoEl.value)} · £${total}${bkStr}`);
});
syncGuests();
renderWidget();
// ── Reserve footer form ───────────────────────────────────────────────────────
document.getElementById("reserveFooter").addEventListener("submit", (e) => {
e.preventDefault();
const name = document.getElementById("rfn").value.trim();
const email = document.getElementById("rfe").value.trim();
const msg = document.getElementById("rfm").value.trim();
if (!name) {
showToast("Please enter your name.");
return;
}
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
showToast("Please enter a valid email address.");
return;
}
const extra = msg ? " We've noted your message." : "";
showToast(`✉ Enquiry sent, ${name.split(" ")[0]}! We'll reply within a few hours.${extra}`);
e.target.reset();
});<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;600;700&family=Lora:ital,wght@0,400;0,600;0,700;1,400;1,600&display=swap"
/>
<link rel="stylesheet" href="style.css" />
<title>Rosehip Inn · Chipping Campden · Cotswolds</title>
</head>
<body>
<!-- ── Sticky nav ── -->
<header class="nav" id="nav">
<a class="brand" href="#">
<span class="brand-mark">🌹</span>
<span class="brand-name">Rosehip Inn</span>
</a>
<nav class="nav-links">
<a href="#rooms">Rooms</a>
<a href="#breakfast">Breakfast</a>
<a href="#story">Our story</a>
<a href="#find-us">Find us</a>
</nav>
<a class="nav-cta" href="#reserve">Book a room</a>
</header>
<!-- ── Hero ── -->
<section class="hero" id="top">
<div class="hero-bg"></div>
<div class="hero-inner">
<div class="hero-copy">
<p class="handwritten-tag">Chipping Campden · Cotswolds</p>
<h1>Home away<br />from home.</h1>
<p class="lede">
A 17th-century farmhouse inn with four cosy rooms, garden views, and a homemade
breakfast that guests talk about for years. We've been welcoming walkers, dreamers,
and honeymooners since 1994.
</p>
<div class="hero-perks">
<span>🍳 Homemade breakfast</span>
<span>🌿 Garden rooms</span>
<span>🔥 Open fireplaces</span>
</div>
</div>
<!-- Reservation widget -->
<form class="rwidget" id="reserveWidget" autocomplete="off">
<div class="rw-title">Reserve your room</div>
<div class="rw-row">
<div class="rw-field">
<label for="rci">Arrive</label>
<input type="date" id="rci" name="rci" />
</div>
<div class="rw-field">
<label for="rco">Depart</label>
<input type="date" id="rco" name="rco" />
</div>
</div>
<div class="rw-field">
<label for="rroom">Room</label>
<select id="rroom" name="rroom">
<option value="rose">Rose Room — £95/night</option>
<option value="orchard" selected>Orchard Room — £110/night</option>
<option value="lavender">Lavender Suite — £145/night</option>
</select>
</div>
<div class="rw-row">
<div class="rw-field">
<label>Guests</label>
<div class="gest-row">
<button type="button" id="gm" class="gest-btn" aria-label="Fewer guests">−</button>
<span id="gv">2</span>
<button type="button" id="gp" class="gest-btn" aria-label="More guests">+</button>
</div>
</div>
<div class="rw-field nights-col">
<label>Nights</label>
<span class="nights-num" id="rNights">—</span>
</div>
</div>
<label class="bkfast-toggle">
<input type="checkbox" id="bkfast" checked />
<span class="bk-track"></span>
Include breakfast (+£18/night/guest)
</label>
<div class="rw-total" id="rTotal">Select dates to calculate</div>
<button type="submit" class="rw-btn">Check availability</button>
</form>
</div>
</section>
<!-- ── Rooms ── -->
<section class="rooms" id="rooms">
<div class="sec-hd">
<p class="handwritten-eyebrow">Where you'll rest</p>
<h2>Our cosy rooms</h2>
</div>
<div class="room-row">
<article class="rc">
<div class="rc-img rc-img--rose"></div>
<div class="rc-body">
<h3>Rose Room</h3>
<p class="rc-detail">Double · Garden view · Ground floor</p>
<p class="rc-desc">Our most intimate room, papered in vintage rose toile with a wrought-iron bed and a view straight into the cottage garden. Perfect for couples.</p>
<div class="rc-features">
<span>🛏 King bed</span>
<span>🛁 Clawfoot tub</span>
<span>🌸 Garden view</span>
</div>
<div class="rc-price">from <strong>£95</strong> <span>/night</span></div>
</div>
</article>
<article class="rc rc--pick">
<div class="rc-ribbon">Guest favourite</div>
<div class="rc-img rc-img--orchard"></div>
<div class="rc-body">
<h3>Orchard Room</h3>
<p class="rc-detail">Double · Orchard view · First floor</p>
<p class="rc-desc">Exposed oak beams, a window seat overlooking the apple orchard, and a super-king bed with our own goose-down duvet. The room guests re-book most often.</p>
<div class="rc-features">
<span>🛏 Super-king</span>
<span>🚿 Rain shower</span>
<span>🍏 Orchard view</span>
</div>
<div class="rc-price">from <strong>£110</strong> <span>/night</span></div>
</div>
</article>
<article class="rc">
<div class="rc-img rc-img--lavender"></div>
<div class="rc-body">
<h3>Lavender Suite</h3>
<p class="rc-detail">Suite · Countryside view · First floor</p>
<p class="rc-desc">A full suite with a separate sitting area, vintage writing desk, and roll-top bath. Honeymooners and anniversary guests call this their favourite place on earth.</p>
<div class="rc-features">
<span>🛏 King bed</span>
<span>🛁 Roll-top bath</span>
<span>🌄 Valley view</span>
</div>
<div class="rc-price">from <strong>£145</strong> <span>/night</span></div>
</div>
</article>
</div>
</section>
<!-- ── Breakfast ── -->
<section class="breakfast" id="breakfast">
<div class="bk-inner">
<div class="bk-copy">
<p class="handwritten-eyebrow handwritten-eyebrow--cream">the best part of waking up</p>
<h2>Breakfast, made with love.</h2>
<p class="bk-lede">Served 08:00–10:00 in the dining room or, on sunny mornings, in the garden. Everything sourced within ten miles. Nothing from a tin.</p>
<ul class="bk-menu">
<li>
<strong>Full Cotswolds</strong>
<span>Free-range eggs, local sausage, black pudding, sourdough toast, homemade marmalade</span>
</li>
<li>
<strong>Garden Plate</strong>
<span>Smoked salmon, avocado, soft-boiled eggs, rye bread, dill butter</span>
</li>
<li>
<strong>Porridge Bar</strong>
<span>Stone-ground oats, warm honey, fresh berries, toasted seeds, cream</span>
</li>
<li>
<strong>Pastry & Fruit</strong>
<span>Croissants, pain au chocolat, seasonal fruit, yoghurt, granola</span>
</li>
</ul>
<p class="bk-note">Dietary requirements? Just ask when booking — we accommodate everything.</p>
</div>
<div class="bk-visual">
<div class="bk-plate">
<span class="bk-emoji">🍳</span>
<span class="bk-emoji bk-emoji--2">🥐</span>
<span class="bk-emoji bk-emoji--3">☕</span>
<span class="bk-emoji bk-emoji--4">🍓</span>
</div>
<p class="bk-caption">Served 08:00 – 10:00 daily</p>
</div>
</div>
</section>
<!-- ── Story ── -->
<section class="story" id="story">
<div class="story-inner">
<div class="story-img"></div>
<div class="story-copy">
<p class="handwritten-eyebrow">our story</p>
<h2>Three decades<br />of warm welcomes.</h2>
<p>
Rosehip Inn has been in the Fairweather family since 1994, when Margaret and David
converted their Cotswold-stone farmhouse into four letting rooms. Today their daughter
Clara runs the inn with her partner Tom, keeping every last original fireplace, tile,
and sash window intact.
</p>
<p>
We grow much of our own fruit and veg in the walled kitchen garden. Our hens supply
the breakfast eggs. The apple trees in the orchard become our annual press batch —
a bottle of Rosehip cider waits on every pillow at check-in.
</p>
<div class="story-nums">
<div class="snum"><strong>30+</strong><span>years open</span></div>
<div class="snum"><strong>4.9★</strong><span>on Tripadvisor</span></div>
<div class="snum"><strong>4</strong><span>cosy rooms</span></div>
</div>
</div>
</div>
</section>
<!-- ── Find us ── -->
<section class="find-us" id="find-us">
<div class="find-inner">
<div class="find-info">
<p class="handwritten-eyebrow">getting here</p>
<h2>Hours & directions</h2>
<ul class="hours">
<li><span>Check-in</span><strong>15:00 – 20:00</strong></li>
<li><span>Check-out</span><strong>until 11:00</strong></li>
<li><span>Breakfast</span><strong>08:00 – 10:00</strong></li>
<li><span>Arrivals by arrangement</span><strong>until 22:00</strong></li>
</ul>
<div class="address">
<p class="addr-name">Rosehip Inn</p>
<p>Wool Lane, Chipping Campden</p>
<p>Gloucestershire GL55 6AU</p>
<p>+44 1386 840 290</p>
</div>
</div>
<div class="map-wrap">
<div class="map-bg"></div>
<div class="map-dot-wrap">
<div class="map-dot-outer"></div>
<div class="map-dot-inner"></div>
</div>
<div class="map-card">
<strong>Rosehip Inn</strong>
<span>Chipping Campden, Cotswolds</span>
</div>
</div>
</div>
</section>
<!-- ── Reserve footer ── -->
<section class="reserve" id="reserve">
<div class="reserve-wrap">
<div class="reserve-copy">
<p class="handwritten-eyebrow handwritten-eyebrow--terra">book directly with us</p>
<h2>Stay at Rosehip.</h2>
<p>No booking fees when you reserve directly. Free cancellation up to 5 days before arrival. We'll even leave a cider on your pillow.</p>
</div>
<form class="reserve-form" id="reserveFooter">
<input type="text" id="rfn" placeholder="Your name" autocomplete="name" />
<input type="email" id="rfe" placeholder="Email address" autocomplete="email" />
<textarea id="rfm" placeholder="Anything we should know? (dietary needs, special occasion…)" rows="3"></textarea>
<button type="submit">Send enquiry 🌹</button>
</form>
</div>
</section>
<div class="toast" id="toast" hidden role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Bed & Breakfast Inn Landing
A homey, cream-and-sage single-page landing for Rosehip Inn — a family-run countryside B&B in the Cotswolds. The page flows through a hand-painted-style hero with an inline reservation widget, three cozy room cards with CSS-gradient imagery, a breakfast menu section, a host story/about block with warm stats, and a location + hours strip with a CSS map placeholder. The reservation widget calculates stay totals live, lets guests toggle breakfast inclusion, validates dates, and fires a toast on submit. A sticky nav appears on scroll. Layout collapses responsively at 960 px and 560 px.