App

Mobile app

Your projects, in your pocket

Review pages, approve changes and get notified when something needs your attention, from anywhere.

  • Offline drafts
  • Push notifications
  • Face ID login

4.9 rating on the App Store

@use 'sprucecss/scss/spruce' as *;

.app-block {
  overflow: hidden;
  padding-block: spacer-clamp('xl', 'xxl');

  &__inner {
    align-items: center;
    background-color: color('surface-muted');
    border-radius: radius('lg');
    display: grid;
    gap: spacer-clamp('l', 'xl');
    padding: spacer-clamp('m', 'xl');

    @include breakpoint('md') {
      grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    }
  }

  &__content {
    @include layout-stack('m');
  }

  &__eyebrow {
    color: color('primary');
    font-weight: 700;
  }

  &__title {
    font-size: responsive-font-size(2.75rem, 35, '3vw + 1rem');
  }

  &__text {
    color: color('muted');
    font-size: config('font-size-lead', $typography);
  }

  &__points {
    list-style: none;
    padding: 0;
    @include layout-cluster('xs');

    li {
      background-color: color('surface');
      border: config('border-width-base', $display) solid color('border');
      border-radius: radius('pill');
      font-size: config('font-size-sm', $typography);
      margin: 0 !important;
      padding-block: spacer('xxs');
      padding-inline: spacer('s');
    }
  }

  &__stores {
    @include layout-cluster('s');
  }

  &__store {
    align-items: center;
    background-color: color('heading');
    border-radius: radius('md');
    color: color('background');
    display: inline-flex;
    font-weight: 700;
    gap: spacer('xs');
    line-height: 1.2;
    padding-block: spacer('xs');
    padding-inline: spacer('s') spacer('m');
    text-decoration: none;
    @include transition($property: 'opacity');

    &:hover {
      color: color('background');
      opacity: 0.85;
    }

    svg {
      block-size: 1.5rem;
      inline-size: 1.5rem;
    }

    small {
      display: block;
      font-size: 0.7rem;
      font-weight: 400;
    }
  }

  &__rating {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
  }

  &__device {
    display: flex;
    justify-content: center;
  }

  &__phone {
    aspect-ratio: 9 / 19;
    background-color: color('heading');
    border-radius: 2.5rem;
    box-shadow: shadow('xl');
    inline-size: min(17rem, 80%);
    padding: 0.6rem;
    rotate: -4deg;

    img,
    svg {
      block-size: 100%;
      border-radius: 2rem;
      display: block;
      inline-size: 100%;
      object-fit: cover;
    }
  }

  // The illustrated screen follows the color tokens (and so the dark mode and the styles).
  &__screen-bg {
    fill: color('background');
  }

  &__screen-card {
    fill: color('surface');
    stroke: color('border');
  }

  &__screen-ink {
    fill: color('heading');
  }

  &__screen-muted {
    fill: color('border');
  }

  &__screen-accent {
    fill: color('primary');
  }

  &__screen-accent-soft {
    fill: color-alpha('primary', 0.2);
  }

  &__screen-track {
    fill: none;
    stroke: color('border');
    stroke-width: 10;
  }

  &__screen-arc {
    fill: none;
    stroke: color('primary');
    stroke-linecap: round;
    stroke-width: 10;
  }

  &__screen-check {
    fill: none;
    stroke: color('background');
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 2.5;
  }
}

[dir='rtl'] .app-block__phone {
  rotate: 4deg;
}
<section class="app-block" aria-labelledby="app-title">
    <div class="container">
        <div class="app-block__inner">
            <div class="app-block__content">
                <p class="app-block__eyebrow">Mobile app</p>
                <h2 class="app-block__title" id="app-title">Your projects, in your pocket</h2>
                <p class="app-block__text">Review pages, approve changes and get notified when something needs your attention, from anywhere.</p>
                <ul class="app-block__points" role="list">
                    <li>Offline drafts</li>
                    <li>Push notifications</li>
                    <li>Face ID login</li>
                </ul>
                <div class="app-block__stores">
                    <a class="app-block__store" href="#"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M16.4 12.6c0-2.5 2-3.7 2.1-3.8-1.2-1.7-3-1.9-3.6-2-1.5-.2-3 .9-3.8.9-.8 0-2-.9-3.3-.9-1.7 0-3.2 1-4.1 2.5-1.8 3.1-.5 7.6 1.3 10.1.8 1.2 1.8 2.6 3.1 2.5 1.2 0 1.7-.8 3.2-.8s1.9.8 3.2.8c1.3 0 2.2-1.2 3-2.4.9-1.4 1.3-2.7 1.3-2.8-.1 0-2.4-.9-2.4-4.1zM14 5.2c.7-.8 1.1-1.9 1-3-1 0-2.1.7-2.8 1.5-.6.7-1.2 1.8-1 2.9 1.1.1 2.1-.6 2.8-1.4z"/></svg><span><small>Download on the</small> App Store</span></a>
                    <a class="app-block__store" href="#"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M4 2.5v19c0 .6.6.9 1.1.6L21 12.9c.5-.3.5-1 0-1.3L5.1 1.9C4.6 1.6 4 1.9 4 2.5z"/></svg><span><small>Get it on</small> Google Play</span></a>
                </div>
                <p class="app-block__rating">4.9 rating on the App Store</p>
            </div>
            <div class="app-block__device">
                <div class="app-block__phone">
                    <svg class="app-block__screen" viewBox="0 0 270 570" role="img" aria-label="The mobile app showing today&#39;s project progress and tasks." xmlns="http://www.w3.org/2000/svg">
                        <rect class="app-block__screen-bg" width="270" height="570"/>
                        <rect class="app-block__screen-ink" x="24" y="22" width="34" height="8" rx="4"/>
                        <rect class="app-block__screen-ink" x="214" y="22" width="32" height="8" rx="4"/>
                        <rect class="app-block__screen-muted" x="24" y="66" width="70" height="10" rx="5"/>
                        <rect class="app-block__screen-ink" x="24" y="86" width="150" height="18" rx="9"/>
                        <circle class="app-block__screen-accent-soft" cx="232" cy="88" r="16"/>
                        <rect class="app-block__screen-card" x="24" y="128" width="222" height="132" rx="20"/>
                        <circle class="app-block__screen-track" cx="88" cy="194" r="38"/>
                        <circle class="app-block__screen-arc" cx="88" cy="194" r="38" pathLength="100" stroke-dasharray="72 100" transform="rotate(-90 88 194)"/>
                        <rect class="app-block__screen-ink" x="74" y="188" width="28" height="12" rx="6"/>
                        <rect class="app-block__screen-muted" x="146" y="168" width="70" height="9" rx="4.5"/>
                        <rect class="app-block__screen-ink" x="146" y="186" width="54" height="14" rx="7"/>
                        <rect class="app-block__screen-muted" x="146" y="212" width="80" height="9" rx="4.5"/>
                        <rect class="app-block__screen-muted" x="24" y="290" width="60" height="10" rx="5"/>
                        <g>
                            <rect class="app-block__screen-card" x="24" y="314" width="222" height="52" rx="16"/>
                            <circle class="app-block__screen-accent" cx="52" cy="340" r="12"/>
                            <path class="app-block__screen-check" d="m46.5 340 4 4 7-8"/>
                            <rect class="app-block__screen-ink" x="76" y="333" width="110" height="9" rx="4.5"/>
                            <rect class="app-block__screen-muted" x="76" y="347" width="64" height="7" rx="3.5"/>
                        </g>
                        <g>
                            <rect class="app-block__screen-card" x="24" y="376" width="222" height="52" rx="16"/>
                            <circle class="app-block__screen-accent" cx="52" cy="402" r="12"/>
                            <path class="app-block__screen-check" d="m46.5 402 4 4 7-8"/>
                            <rect class="app-block__screen-ink" x="76" y="395" width="90" height="9" rx="4.5"/>
                            <rect class="app-block__screen-muted" x="76" y="409" width="80" height="7" rx="3.5"/>
                        </g>
                        <g>
                            <rect class="app-block__screen-card" x="24" y="438" width="222" height="52" rx="16"/>
                            <circle class="app-block__screen-track" cx="52" cy="464" r="11"/>
                            <rect class="app-block__screen-ink" x="76" y="457" width="120" height="9" rx="4.5"/>
                            <rect class="app-block__screen-muted" x="76" y="471" width="56" height="7" rx="3.5"/>
                        </g>
                        <rect class="app-block__screen-card" x="24" y="510" width="222" height="40" rx="20"/>
                        <circle class="app-block__screen-accent" cx="62" cy="530" r="6"/>
                        <circle class="app-block__screen-muted" cx="111" cy="530" r="6"/>
                        <circle class="app-block__screen-muted" cx="159" cy="530" r="6"/>
                        <circle class="app-block__screen-muted" cx="208" cy="530" r="6"/>
                    </svg>
                </div>
            </div>
        </div>
    </div>
</section>

App

On this page

A mobile app promotion with store buttons, highlights and a phone mockup.

Technical Details

  • The store buttons are links styled with the heading and background colors, so they invert correctly in dark mode and every style. Use the official badges if the stores' guidelines require it.
  • The phone frame is pure CSS around a screenshot; its tilt mirrors in RTL.
  • Two columns from the md breakpoint.
  • Override the content with appBlock.

Documentation

Learn about Spruce CSS through our extensive documentation.

Components

Explore our UI library of accessible components built with Spruce CSS.

Blocks and Pages

Full-width page blocks and complete page templates, ready to copy.

Find us on GitHub

Did you find a bug? Have an idea or a question? Please open an issue to help us develop the project.