Tailwind
This commit is contained in:
parent
ee265b679d
commit
a1f1b5902e
15 changed files with 177 additions and 421 deletions
|
|
@ -12,6 +12,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
git \
|
||||
unzip \
|
||||
locales \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \
|
||||
|
|
@ -33,7 +36,9 @@ WORKDIR /var/www/html
|
|||
# To use ../drupal instead, add it as a path repository in composer.json:
|
||||
# "repositories": [{"type": "path", "url": "../drupal/core", "options": {"symlink": false}}]
|
||||
# then bump drupal/core-recommended to "11.x-dev@dev" and rebuild.
|
||||
COPY composer.json ./
|
||||
COPY composer.json package.json tailwind.config.js ./
|
||||
|
||||
RUN npm install --include=dev
|
||||
|
||||
RUN composer config repositories.drupal composer https://packages.drupal.org/8
|
||||
|
||||
|
|
@ -59,6 +64,8 @@ COPY web/sites/default/settings.php web/sites/default/settings.php
|
|||
COPY web/sites/default/files/ web/sites/default/files/
|
||||
COPY web/modules/custom/ web/modules/custom/
|
||||
|
||||
RUN npm run build
|
||||
|
||||
ARG FULLCALENDAR_VERSION=6.1.15
|
||||
RUN curl -fsSL "https://cdn.jsdelivr.net/npm/fullcalendar@${FULLCALENDAR_VERSION}/index.global.min.js" \
|
||||
-o web/modules/custom/riverside_pt/js/fullcalendar.min.js
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ services:
|
|||
ADMIN_PASS: "${ADMIN_PASS:-admin}"
|
||||
HASH_SALT: "${HASH_SALT:-replace-this-in-production-with-a-long-random-string}"
|
||||
POSTMARK_API_KEY: "${POSTMARK_API_KEY:-}"
|
||||
BASE_URL: "${BASE_URL:-http://localhost:8080}"
|
||||
volumes:
|
||||
- ./web/sites/default/files:/var/www/html/web/sites/default/files
|
||||
- ./web/modules/custom:/var/www/html/web/modules/custom
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ else
|
|||
echo "[entrypoint] No config to import, continuing."
|
||||
fi
|
||||
|
||||
npm run build --prefix /var/www/html >/dev/null 2>&1 && echo "[entrypoint] Tailwind built." || echo "[entrypoint] WARNING: Tailwind build failed."
|
||||
|
||||
$DRUSH cache:rebuild >/dev/null 2>&1 && echo "[entrypoint] Cache rebuilt."
|
||||
|
||||
echo "[entrypoint] Starting services..."
|
||||
|
|
|
|||
11
package.json
Normal file
11
package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "riverside-therapeutics",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"watch": "tailwindcss -i ./web/modules/custom/riverside_pt/css/tailwind.css -o ./web/modules/custom/riverside_pt/css/app.css --watch",
|
||||
"build": "tailwindcss -i ./web/modules/custom/riverside_pt/css/tailwind.css -o ./web/modules/custom/riverside_pt/css/app.css --minify"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^3.4.17"
|
||||
}
|
||||
}
|
||||
11
tailwind.config.js
Normal file
11
tailwind.config.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./web/modules/custom/riverside_pt/templates/**/*.twig',
|
||||
'./web/modules/custom/riverside_pt/src/**/*.php',
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
1
web/modules/custom/riverside_pt/css/app.css
Normal file
1
web/modules/custom/riverside_pt/css/app.css
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,147 +0,0 @@
|
|||
/* Hide Drupal's default page-title block on the front page — our H1 is inside the hero */
|
||||
.path-frontpage .block-page-title-block {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-wrapper {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
/* ── Hero ───────────────────────────────────────────────────── */
|
||||
.rpt-hero {
|
||||
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
||||
padding: 5rem 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rpt-hero__inner {
|
||||
max-width: 680px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.rpt-hero__heading {
|
||||
font-size: clamp(2rem, 5vw, 3.25rem);
|
||||
font-weight: 700;
|
||||
color: #1e3a8a;
|
||||
line-height: 1.15;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.rpt-hero__body {
|
||||
font-size: 1.125rem;
|
||||
color: #4b5563;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.rpt-hero__actions {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ── Shared buttons ─────────────────────────────────────────── */
|
||||
.rpt-btn {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 999px;
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
text-decoration: none;
|
||||
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rpt-btn--primary {
|
||||
background: #3b82f6;
|
||||
color: #fff;
|
||||
border: 2px solid #3b82f6;
|
||||
}
|
||||
|
||||
.rpt-btn--primary:hover,
|
||||
.rpt-btn--primary:focus {
|
||||
background: #1d4ed8;
|
||||
border-color: #1d4ed8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.rpt-btn--secondary {
|
||||
background: transparent;
|
||||
color: #3b82f6;
|
||||
border: 2px solid #3b82f6;
|
||||
}
|
||||
|
||||
.rpt-btn--secondary:hover,
|
||||
.rpt-btn--secondary:focus {
|
||||
background: #3b82f6;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.rpt-btn--outline {
|
||||
background: transparent;
|
||||
color: #3b82f6;
|
||||
border: 1px solid #3b82f6;
|
||||
border-radius: 4px;
|
||||
font-size: 0.875rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.rpt-btn--outline:hover,
|
||||
.rpt-btn--outline:focus {
|
||||
background: #3b82f6;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ── Services section ───────────────────────────────────────── */
|
||||
.rpt-services {
|
||||
padding: 4rem 1.5rem;
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.rpt-services__header {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.rpt-services__heading {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #1e3a8a;
|
||||
margin-bottom: 0.375rem;
|
||||
}
|
||||
|
||||
.rpt-services__subtitle {
|
||||
font-size: 1.0625rem;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.rpt-services__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 1.5rem;
|
||||
max-width: 1040px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.rpt-service-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.rpt-service-card__title {
|
||||
font-size: 1.0625rem;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.rpt-service-card__body {
|
||||
font-size: 0.9375rem;
|
||||
color: #6b7280;
|
||||
line-height: 1.6;
|
||||
flex: 1;
|
||||
}
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
/* ── Hide Olivero's built-in header entirely ─────────────── */
|
||||
.site-header,
|
||||
.sticky-header-toggle,
|
||||
.social-bar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Push page content below the fixed header */
|
||||
body {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
/* ── Custom header shell ─────────────────────────────────── */
|
||||
.rpt-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
height: 80px;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.rpt-header__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
/* ── Brand / site name ───────────────────────────────────── */
|
||||
.rpt-header__brand {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
color: #1e3a5f;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.rpt-header__brand:hover {
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
/* ── Nav list ────────────────────────────────────────────── */
|
||||
.rpt-header__nav {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.rpt-header__list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.rpt-header__items--cta {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* ── Nav links ───────────────────────────────────────────── */
|
||||
.rpt-header__link {
|
||||
display: block;
|
||||
font-size: 0.9375rem;
|
||||
font-weight: 400;
|
||||
color: #374151;
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 0.875rem;
|
||||
}
|
||||
|
||||
.rpt-header__link:hover,
|
||||
.rpt-header__link:focus {
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
.rpt-header__link.is-active {
|
||||
color: #1e3a8a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── CTA button ──────────────────────────────────────────── */
|
||||
.rpt-header__cta {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1.25rem;
|
||||
background: #1e3a5f;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
border: 1.5px solid #1e3a5f;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rpt-header__cta:hover,
|
||||
.rpt-header__cta:focus {
|
||||
background: #152a45;
|
||||
border-color: #152a45;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.rpt-header__item--cta {
|
||||
padding: 0.5rem 1.5rem;
|
||||
}
|
||||
|
||||
|
||||
/* ── Hamburger button (hidden on desktop) ────────────────── */
|
||||
.rpt-header__hamburger {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
padding: 8px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.rpt-header__hamburger span {
|
||||
display: block;
|
||||
height: 4px;
|
||||
background: #1e3a5f;
|
||||
border-radius: 3px;
|
||||
transition: transform 0.25s ease, opacity 0.2s ease, width 0.25s ease;
|
||||
}
|
||||
|
||||
.rpt-header__hamburger span:nth-child(1) { width: 45%; }
|
||||
.rpt-header__hamburger span:nth-child(2) { width: 100%; }
|
||||
.rpt-header__hamburger span:nth-child(3) { width: 45%; align-self: flex-end; }
|
||||
|
||||
/* Animate to X when open */
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(1) {
|
||||
width: 100%;
|
||||
transform: translateY(10px) rotate(45deg);
|
||||
}
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(3) {
|
||||
width: 100%;
|
||||
transform: translateY(-10px) rotate(-45deg);
|
||||
}
|
||||
|
||||
/* ── Mobile layout ───────────────────────────────────────── */
|
||||
@media (max-width: 768px) {
|
||||
.rpt-header__hamburger {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.rpt-header__nav {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
transition: max-height 0.3s ease, opacity 0.25s ease;
|
||||
}
|
||||
|
||||
.rpt-header__nav.is-open {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.rpt-header__list {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
|
||||
.rpt-header__link {
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.rpt-header__cta {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
60
web/modules/custom/riverside_pt/css/tailwind.css
Normal file
60
web/modules/custom/riverside_pt/css/tailwind.css
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
padding-top: 80px;
|
||||
}
|
||||
/* Neutralise any theme container constraints */
|
||||
.page-wrapper {
|
||||
max-width: none;
|
||||
padding-inline: 0;
|
||||
}
|
||||
/* Hide Olivero/theme chrome we don't use */
|
||||
.site-header,
|
||||
.sticky-header-toggle,
|
||||
.social-bar {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* Mobile nav: max-height slide can't be expressed with utilities alone */
|
||||
@media (max-width: 767px) {
|
||||
#rpt-main-nav {
|
||||
flex: none;
|
||||
position: absolute;
|
||||
top: 5rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
transition: max-height 0.3s ease, opacity 0.25s ease;
|
||||
}
|
||||
#rpt-main-nav.is-open {
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
}
|
||||
#rpt-main-nav ul {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hamburger open-state animation */
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(1) {
|
||||
width: 100% !important;
|
||||
transform: translateY(10px) rotate(45deg);
|
||||
}
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
.rpt-header__hamburger[aria-expanded="true"] span:nth-child(3) {
|
||||
width: 100% !important;
|
||||
transform: translateY(-10px) rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,7 @@
|
|||
front:
|
||||
app:
|
||||
css:
|
||||
theme:
|
||||
css/front.css: {}
|
||||
|
||||
navigation:
|
||||
css:
|
||||
theme:
|
||||
css/nav.css: {}
|
||||
css/app.css: {}
|
||||
js:
|
||||
js/nav.js: {}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use Drupal\Core\Link;
|
|||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
function riverside_pt_page_attachments(array &$attachments): void {
|
||||
$attachments['#attached']['library'][] = 'riverside_pt/navigation';
|
||||
$attachments['#attached']['library'][] = 'riverside_pt/app';
|
||||
}
|
||||
|
||||
function riverside_pt_theme(): array {
|
||||
|
|
@ -18,6 +18,9 @@ function riverside_pt_theme(): array {
|
|||
'current_path' => NULL,
|
||||
],
|
||||
],
|
||||
'riverside_pt_home' => [
|
||||
'variables' => [],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,55 +7,7 @@ use Drupal\Core\Controller\ControllerBase;
|
|||
class HomeController extends ControllerBase {
|
||||
|
||||
public function page(): array {
|
||||
return [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => self::template(),
|
||||
'#attached' => ['library' => ['riverside_pt/front']],
|
||||
];
|
||||
}
|
||||
|
||||
private static function template(): string {
|
||||
return <<<'TWIG'
|
||||
<section class="rpt-hero">
|
||||
<div class="rpt-hero__inner">
|
||||
<h1 class="rpt-hero__heading">Heal your body</h1>
|
||||
<p class="rpt-hero__body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
||||
<div class="rpt-hero__actions">
|
||||
<a href="/schedule" class="rpt-btn rpt-btn--primary">Book an Appointment</a>
|
||||
<a href="/services" class="rpt-btn rpt-btn--secondary">View Our Services</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="rpt-services">
|
||||
<div class="rpt-services__header">
|
||||
<h2 class="rpt-services__heading">Bringing Relief</h2>
|
||||
<p class="rpt-services__subtitle">Our wide range of services</p>
|
||||
</div>
|
||||
<div class="rpt-services__grid">
|
||||
<div class="rpt-service-card">
|
||||
<h3 class="rpt-service-card__title">Diagnostic Evaluation</h3>
|
||||
<p class="rpt-service-card__body">Comprehensive assessment to identify the root cause of your pain and build a personalized recovery plan.</p>
|
||||
<a href="/services" class="rpt-btn rpt-btn--outline">More Info</a>
|
||||
</div>
|
||||
<div class="rpt-service-card">
|
||||
<h3 class="rpt-service-card__title">Sports Rehabilitation</h3>
|
||||
<p class="rpt-service-card__body">Targeted programs to help athletes recover from injury and return to peak performance safely.</p>
|
||||
<a href="/services" class="rpt-btn rpt-btn--outline">More Info</a>
|
||||
</div>
|
||||
<div class="rpt-service-card">
|
||||
<h3 class="rpt-service-card__title">Pre/Post-Surgical Rehab</h3>
|
||||
<p class="rpt-service-card__body">Expert care before and after surgery to maximize recovery outcomes and restore full function.</p>
|
||||
<a href="/services" class="rpt-btn rpt-btn--outline">More Info</a>
|
||||
</div>
|
||||
<div class="rpt-service-card">
|
||||
<h3 class="rpt-service-card__title">Neurological Physical Therapy</h3>
|
||||
<p class="rpt-service-card__body">Specialized therapy for nervous system conditions, helping you regain strength and independence.</p>
|
||||
<a href="/services" class="rpt-btn rpt-btn--outline">More Info</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
TWIG;
|
||||
return ['#theme' => 'riverside_pt_home'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
<header class="rpt-header" role="banner">
|
||||
<div class="rpt-header__inner">
|
||||
<header class="rpt-header fixed top-0 left-0 right-0 z-50 h-20 bg-white shadow-sm" role="banner">
|
||||
<div class="flex items-center h-full max-w-[1200px] mx-auto px-6 gap-8">
|
||||
|
||||
<a class="rpt-header__brand" href="{{ home_url }}">{{ site_name }}</a>
|
||||
<a class="text-lg font-bold text-[#1e3a5f] no-underline whitespace-nowrap shrink-0 hover:text-[#1e3a8a]"
|
||||
href="{{ home_url }}">{{ site_name }}</a>
|
||||
|
||||
<nav class="rpt-header__nav" id="rpt-main-nav" aria-label="Main navigation">
|
||||
<ul class="rpt-header__list">
|
||||
<nav class="flex-1 min-w-0" id="rpt-main-nav" aria-label="Main navigation">
|
||||
<ul class="flex items-center list-none m-0 p-0 gap-1">
|
||||
{% for item in menu_items %}
|
||||
{% if not item.is_cta %}
|
||||
<li class="rpt-header__item">
|
||||
<a class="rpt-header__link{% if current_path == item.url %} is-active{% endif %}"
|
||||
<li>
|
||||
<a class="block text-[15px] text-gray-700 no-underline px-3.5 py-1 hover:text-[#1e3a8a]{% if current_path == item.url %} text-[#1e3a8a] font-medium{% endif %}"
|
||||
href="{{ item.url }}">{{ item.title }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
|
@ -18,29 +19,26 @@
|
|||
{% for item in menu_items %}
|
||||
{% if item.is_cta %}{% set has_cta = true %}{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if has_cta %}
|
||||
<div class="rpt-header__items--cta">
|
||||
<li class="ml-auto px-6">
|
||||
{% for item in menu_items %}
|
||||
{% if item.is_cta %}
|
||||
<li class="rpt-header__item rpt-header__item--cta">
|
||||
<a class="rpt-header__cta" href="{{ item.url }}">{{ item.title }}</a>
|
||||
</li>
|
||||
<a class="inline-block px-5 py-2 bg-[#1e3a5f] text-white text-sm font-medium no-underline rounded border border-[#1e3a5f] whitespace-nowrap transition-colors hover:bg-[#152a45] hover:border-[#152a45] hover:text-white"
|
||||
href="{{ item.url }}">{{ item.title }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<button class="rpt-header__hamburger"
|
||||
<button class="rpt-header__hamburger flex md:hidden flex-col justify-center gap-1.5 w-11 h-11 p-2 bg-transparent border-0 cursor-pointer shrink-0 ml-auto"
|
||||
aria-expanded="false"
|
||||
aria-controls="rpt-main-nav"
|
||||
aria-label="Toggle navigation">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span class="block h-1 bg-[#1e3a5f] rounded-[3px] w-[45%] transition-transform duration-[250ms] ease-in-out"></span>
|
||||
<span class="block h-1 bg-[#1e3a5f] rounded-[3px] w-full transition-[transform,opacity] duration-200 ease-in-out"></span>
|
||||
<span class="block h-1 bg-[#1e3a5f] rounded-[3px] w-[45%] self-end transition-transform duration-[250ms] ease-in-out"></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
<section class="relative bg-[#aac6c6] min-h-[560px]">
|
||||
|
||||
{# Box 1: Image — spacer 8% | image 58% | spacer 34% #}
|
||||
<div class="absolute inset-0 flex">
|
||||
<div class="basis-[8%] grow-[2]"></div>
|
||||
<div class="basis-[58%] grow self-stretch">
|
||||
<img src="/modules/custom/riverside_pt/images/hero.jpg" alt="" class="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div class="basis-[34%] grow-[2]"></div>
|
||||
</div>
|
||||
|
||||
{# Box 2: Text — spacer 50% | text 38% | spacer 12% #}
|
||||
<div class="relative flex min-h-[560px]">
|
||||
<div class="basis-[50%] grow-[2]"></div>
|
||||
<div class="basis-[38%] grow flex flex-col justify-center py-16 gap-6">
|
||||
<h1 class="text-[clamp(2rem,3.5vw,3.25rem)] font-serif font-normal text-white leading-tight">Restore your strength.<br>Reclaim your life.</h1>
|
||||
<p class="text-white/80 text-lg leading-relaxed">Every new patient starts with a comprehensive diagnostic assessment. From there we build a personalized plan that may include sports rehabilitation, pre- or post-surgical recovery, or neurological physical therapy.</p>
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<a href="/schedule" class="px-8 py-3 bg-[#4a7a8a] text-white text-sm font-medium no-underline transition-colors hover:bg-[#3a6a7a]">Book An Appointment</a>
|
||||
<a href="/services" class="px-8 py-3 border border-white/60 text-white text-sm font-medium no-underline transition-colors hover:bg-white/10">View Our Services</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="basis-[12%] grow-[2]"></div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="py-16 px-6 bg-gray-100">
|
||||
<div class="text-center mb-12">
|
||||
<h2 class="text-3xl font-bold text-blue-900 mb-1.5">Bringing Relief</h2>
|
||||
<p class="text-[17px] text-gray-500">Our wide range of services</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-6 max-w-[1040px] mx-auto">
|
||||
<div class="flex flex-col gap-3 border border-gray-200 rounded-lg p-6 bg-white">
|
||||
<h3 class="text-[17px] font-semibold text-gray-900">Diagnostic Evaluation</h3>
|
||||
<p class="text-[15px] text-gray-500 leading-relaxed flex-1">Comprehensive assessment to identify the root cause of your pain and build a personalized recovery plan.</p>
|
||||
<a href="/services" class="inline-block px-4 py-2 text-[14px] text-blue-500 border border-blue-500 rounded no-underline transition-colors hover:bg-blue-500 hover:text-white">More Info</a>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3 border border-gray-200 rounded-lg p-6 bg-white">
|
||||
<h3 class="text-[17px] font-semibold text-gray-900">Sports Rehabilitation</h3>
|
||||
<p class="text-[15px] text-gray-500 leading-relaxed flex-1">Targeted programs to help athletes recover from injury and return to peak performance safely.</p>
|
||||
<a href="/services" class="inline-block px-4 py-2 text-[14px] text-blue-500 border border-blue-500 rounded no-underline transition-colors hover:bg-blue-500 hover:text-white">More Info</a>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3 border border-gray-200 rounded-lg p-6 bg-white">
|
||||
<h3 class="text-[17px] font-semibold text-gray-900">Pre/Post-Surgical Rehab</h3>
|
||||
<p class="text-[15px] text-gray-500 leading-relaxed flex-1">Expert care before and after surgery to maximize recovery outcomes and restore full function.</p>
|
||||
<a href="/services" class="inline-block px-4 py-2 text-[14px] text-blue-500 border border-blue-500 rounded no-underline transition-colors hover:bg-blue-500 hover:text-white">More Info</a>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3 border border-gray-200 rounded-lg p-6 bg-white">
|
||||
<h3 class="text-[17px] font-semibold text-gray-900">Neurological Physical Therapy</h3>
|
||||
<p class="text-[15px] text-gray-500 leading-relaxed flex-1">Specialized therapy for nervous system conditions, helping you regain strength and independence.</p>
|
||||
<a href="/services" class="inline-block px-4 py-2 text-[14px] text-blue-500 border border-blue-500 rounded no-underline transition-colors hover:bg-blue-500 hover:text-white">More Info</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -28,6 +28,10 @@ if ($postmark_key = getenv('POSTMARK_API_KEY')) {
|
|||
$config['system.performance']['css']['preprocess'] = FALSE;
|
||||
$config['system.performance']['js']['preprocess'] = FALSE;
|
||||
|
||||
if ($base = getenv('BASE_URL')) {
|
||||
$base_url = $base;
|
||||
}
|
||||
|
||||
if ($trusted = getenv('TRUSTED_HOST')) {
|
||||
$settings['trusted_host_patterns'] = ['^' . preg_quote($trusted, '/') . '$'];
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue