diff --git a/package-lock.json b/package-lock.json
index 483e11c9f9cfc3c2029fc9e461982d74352f3a54..b5a27f1721dbf97bfa9673577b4877d018d09869 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14556,6 +14556,17 @@
         }
       }
     },
+    "react-helmet": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
+      "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
+      "requires": {
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.7.2",
+        "react-fast-compare": "^3.1.1",
+        "react-side-effect": "^2.1.0"
+      }
+    },
     "react-intersection-observer": {
       "version": "8.31.0",
       "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-8.31.0.tgz",
@@ -15017,6 +15028,11 @@
         }
       }
     },
+    "react-side-effect": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz",
+      "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ=="
+    },
     "read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
diff --git a/package.json b/package.json
index e344b74b4cbb6446dd5aaade8f2c8fd01224159b..5da46dfc97d04752796c470fad7c0d333269c8e6 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
     "pullstate": "^1.20.5",
     "react": "^16.13.1",
     "react-dom": "^16.13.1",
+    "react-helmet": "^6.1.0",
     "react-intersection-observer": "^8.31.0",
     "react-joyride": "^2.3.0",
     "react-mde": "^11.0.0",
diff --git a/public/favicon.ico b/public/favicon.ico
deleted file mode 100644
index bcd5dfd67cd0361b78123e95c2dd96031f27f743..0000000000000000000000000000000000000000
Binary files a/public/favicon.ico and /dev/null differ
diff --git a/public/img/og.png b/public/img/og.png
new file mode 100644
index 0000000000000000000000000000000000000000..63771e5a7661f12728b76f0aa3ddd32499a54d48
Binary files /dev/null and b/public/img/og.png differ
diff --git a/public/index.html b/public/index.html
index 3fae09c5ba43267bd5a7b910f459ee18ee6d0e08..6e3d8c09dcbc110706d5b29683f38265aadcd2a3 100644
--- a/public/index.html
+++ b/public/index.html
@@ -17,6 +17,11 @@
     <meta property="og:url" content="https://cf2021.pirati.cz/" />
     <meta property="og:type" content="website" />
     <meta property="og:title" content="CF 2021" />
+    <meta property="og:image" content="/img/og.png" />
+    <meta property="og:description" content="Oficiální stránka letošního ročníku Celostátního fóra České pirátské strany." />
+    <meta name="description" content="Oficiální stránka letošního ročníku Celostátního fóra České pirátské strany." />
+
+    <title>CF 2021 | Pirátská strana</title>
     <!--
       manifest.json provides metadata used when your web app is installed on a
       user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
@@ -32,7 +37,6 @@
       Learn how to configure a non-root public URL by running `npm run build`.
     -->
     <link rel="stylesheet" href="%REACT_APP_STYLEGUIDE_URL%/css/styles.css" />
-    <title>CF 2021 | Pirátská strana</title>
     <script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>
   </head>
   <body class="h-screen">
diff --git a/public/logo192.png b/public/logo192.png
deleted file mode 100644
index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000
Binary files a/public/logo192.png and /dev/null differ
diff --git a/public/logo512.png b/public/logo512.png
deleted file mode 100644
index a4e47a6545bc15971f8f63fba70e4013df88a664..0000000000000000000000000000000000000000
Binary files a/public/logo512.png and /dev/null differ
diff --git a/public/manifest.json b/public/manifest.json
index 080d6c77ac21bb2ef88a6992b2b73ad93daaca92..c332442ea6af45bc2030b416f89147067de290dd 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,21 +1,21 @@
 {
-  "short_name": "React App",
-  "name": "Create React App Sample",
+  "short_name": "CF2021",
+  "name": "Celostátní fórum 2021",
   "icons": [
     {
-      "src": "favicon.ico",
-      "sizes": "64x64 32x32 24x24 16x16",
+      "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-32x32.png",
+      "sizes": "32x32 24x24 16x16",
       "type": "image/x-icon"
     },
     {
-      "src": "logo192.png",
-      "type": "image/png",
-      "sizes": "192x192"
+      "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-96x96.png",
+      "sizes": "96x96 64x64",
+      "type": "image/x-icon"
     },
     {
-      "src": "logo512.png",
+      "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-196x196.png",
       "type": "image/png",
-      "sizes": "512x512"
+      "sizes": "192x192 196x196"
     }
   ],
   "start_url": ".",
diff --git a/src/App.jsx b/src/App.jsx
index 1ba3568f3ac2b6bcf3ed6f744f3e315ee7f891f0..0ceedc5779d84bc3c0af762aadde9adc5be5b4af 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,4 +1,5 @@
 import React, { Suspense } from "react";
+import { Helmet } from "react-helmet";
 import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
 import { KeycloakProvider } from "@react-keycloak/web";
 import * as Sentry from "@sentry/react";
@@ -6,10 +7,10 @@ import * as Sentry from "@sentry/react";
 import { loadConfig } from "actions/global-info";
 import { loadMe } from "actions/users";
 import { initializeWSChannel } from "actions/ws";
-import Button from "components/Button";
 import Footer from "components/Footer";
 import Navbar from "components/Navbar";
 import Home from "pages/Home";
+import NotFound from "pages/NotFound";
 import Program from "pages/Program";
 import Protocol from "pages/Protocol";
 import { AuthStore, PostStore } from "stores";
@@ -80,27 +81,23 @@ const LoadingComponent = (
   </div>
 );
 
-const NotFound = () => (
-  <article className="container container--default py-8 lg:py-24">
-    <h1 className="head-alt-base lg:head-alt-lg mb-8">
-      404ka: tak tahle stránka tu není
-    </h1>
-    <p className="text-base lg:text-xl mb-8">
-      Dostal/a ses na takzvanou „<strong>čtyřystačtyřku</strong>“, což znamená,
-      že stránka, kterou jsi se pokusil/a navštívit, na tomhle webu není.
-      Zkontroluj, zda máš správný odkaz.
-    </p>
-    <Button routerTo="/" className="text-base lg:text-xl" hoverActive fullwidth>
-      Přejít na hlavní stránku
-    </Button>
-  </article>
-);
-
 const BaseApp = () => {
   initializeWSChannel.read();
 
   return (
     <Router>
+      <Helmet>
+        <title>CF 2021 | Pirátská strana</title>
+        <meta
+          name="description"
+          content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+        <meta property="og:title" content="CF 2021" />
+        <meta
+          property="og:description"
+          content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+      </Helmet>
       <Navbar />
       <Switch>
         <Route exact path="/" children={<Home />} />
diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx
index ce7d9a0ec8d8c947d6326e9e032ad13af86619d5..34a8dc67b5e4d68c074ffdb6fac0563a8c13b5af 100644
--- a/src/components/Navbar.jsx
+++ b/src/components/Navbar.jsx
@@ -126,6 +126,7 @@ const Navbar = () => {
                   <button
                     onClick={logout}
                     className="text-grey-200 hover:text-white"
+                    title="Odhlásit se"
                   >
                     <i className="ico--log-out"></i>
                   </button>
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index 7b470dcf39748eb4488f5cad8f5fd32c0574d6ee..1115287ce3a4222edeca1c5b09fd91730f4fd43a 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -1,4 +1,5 @@
 import React, { useEffect, useState } from "react";
+import { Helmet } from "react-helmet";
 import Joyride, { EVENTS } from "react-joyride";
 import ReactPlayer from "react-player/lazy";
 import useWindowSize from "@rooks/use-window-size";
@@ -109,6 +110,21 @@ const Home = () => {
 
   return (
     <>
+      <Helmet>
+        <title>Přímý přenos | CF 2021 | Pirátská strana</title>
+        <meta
+          name="description"
+          content="Přímý přenos a diskuse z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+        <meta
+          property="og:title"
+          content="Přímý přenos | CF 2021 | Pirátská strana"
+        />
+        <meta
+          property="og:description"
+          content="Přímý přenos a diskuse z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+      </Helmet>
       <Joyride
         beaconComponent={Beacon}
         continuous={true}
@@ -259,8 +275,7 @@ const Home = () => {
             showAddPostCta={programEntry.discussionOpened}
           />
           {!programEntry.discussionOpened &&
-            isAuthenticated &&
-            !user.isBanned && (
+            (!isAuthenticated || (isAuthenticated && !user.isBanned)) && (
               <p className="leading-normal">
                 Rozprava je uzavřena - příspěvky teď nelze přidávat.
               </p>
diff --git a/src/pages/NotFound.jsx b/src/pages/NotFound.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..ee171f42370e2fec7edddbbad7619e9e8bc2633d
--- /dev/null
+++ b/src/pages/NotFound.jsx
@@ -0,0 +1,35 @@
+import React from "react";
+import { Helmet } from "react-helmet";
+
+import Button from "components/Button";
+
+const NotFound = () => (
+  <>
+    <Helmet>
+      <title>404ka | CF 2021 | Pirátská strana</title>
+      <meta name="description" content="Tahle stránka tu není." />
+      <meta property="og:title" content="404ka | CF 2021 | Pirátská strana" />
+      <meta property="og:description" content="Tahle stránka tu není." />
+    </Helmet>
+    <article className="container container--default py-8 lg:py-24">
+      <h1 className="head-alt-base lg:head-alt-lg mb-8">
+        404ka: tak tahle stránka tu není
+      </h1>
+      <p className="text-base lg:text-xl mb-8">
+        Dostal/a ses na takzvanou „<strong>čtyřystačtyřku</strong>“, což
+        znamená, že stránka, kterou jsi se pokusil/a navštívit, na tomhle webu
+        není. Zkontroluj, zda máš správný odkaz.
+      </p>
+      <Button
+        routerTo="/"
+        className="text-base lg:text-xl"
+        hoverActive
+        fullwidth
+      >
+        Přejít na hlavní stránku
+      </Button>
+    </article>
+  </>
+);
+
+export default NotFound;
diff --git a/src/pages/Program.jsx b/src/pages/Program.jsx
index 7b5c1088499555379829916a0bdeb30303dc5b32..9e78c06e23297a82f877e320a65a6737bf1f09f1 100644
--- a/src/pages/Program.jsx
+++ b/src/pages/Program.jsx
@@ -1,4 +1,5 @@
 import React from "react";
+import { Helmet } from "react-helmet";
 import { Link } from "react-router-dom";
 import { format } from "date-fns";
 
@@ -25,79 +26,96 @@ const Schedule = () => {
   );
 
   return (
-    <article className="container container--default py-8 lg:py-24">
-      <h1 className="head-alt-md lg:head-alt-lg mb-8">Program zasedání</h1>
-      <div className="flex flex-col">
-        {scheduleIds.map((id) => {
-          const isCurrent = id === currentId;
-          const entry = items[id];
-          const fullTitle = `${entry.number}. ${entry.title}`;
-          return (
-            <div
-              className="flex flex-col md:flex-row my-4 duration-300 text-black"
-              key={entry.id}
-            >
-              <div className="w-28 md:text-right">
-                {isCurrent && (
-                  <Chip condensed className="mt-2 mr-2" color="red-600">
-                    Právě probíhá
-                  </Chip>
-                )}
-              </div>
-              <div className="w-full md:w-32 flex flex-row md:flex-col items-center md:items-stretch md:text-right md:pr-8">
-                <p className="head-heavy-xs md:head-heavy-base">
-                  {format(entry.expectedStartAt, "H:mm")}
-                </p>
-                <p className="ml-auto md:ml-0 head-heavy-xs md:head-heavy-xs md:text-grey-200 whitespace-no-wrap">
-                  {format(entry.expectedStartAt, "d. M. Y")}
-                </p>
-              </div>
-              <div className="flex-grow w-full">
-                <h2 className="head-heavy-xs md:head-heavy-base mb-1">
-                  {isCurrent && <Link to="/">{fullTitle}</Link>}
-                  {!isCurrent && fullTitle}
-                </h2>
-                <div className="flex space-x-2">
-                  <strong>Navrhovatel:</strong>
-                  <span>{entry.proposer}</span>
+    <>
+      <Helmet>
+        <title>Program zasedání | CF 2021 | Pirátská strana</title>
+        <meta
+          name="description"
+          content="Přečtěte si program on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+        <meta
+          property="og:title"
+          content="Program zasedání | CF 2021 | Pirátská strana"
+        />
+        <meta
+          property="og:description"
+          content="Přečtěte si program on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+      </Helmet>
+      <article className="container container--default py-8 lg:py-24">
+        <h1 className="head-alt-md lg:head-alt-lg mb-8">Program zasedání</h1>
+        <div className="flex flex-col">
+          {scheduleIds.map((id) => {
+            const isCurrent = id === currentId;
+            const entry = items[id];
+            const fullTitle = `${entry.number}. ${entry.title}`;
+            return (
+              <div
+                className="flex flex-col md:flex-row my-4 duration-300 text-black"
+                key={entry.id}
+              >
+                <div className="w-28 md:text-right">
+                  {isCurrent && (
+                    <Chip condensed className="mt-2 mr-2" color="red-600">
+                      Právě probíhá
+                    </Chip>
+                  )}
                 </div>
-                {entry.description && (
-                  <p className="mt-2 leading-tight max-w-3xl">
-                    {entry.description}
+                <div className="w-full md:w-32 flex flex-row md:flex-col items-center md:items-stretch md:text-right md:pr-8">
+                  <p className="head-heavy-xs md:head-heavy-base">
+                    {format(entry.expectedStartAt, "H:mm")}
                   </p>
-                )}
-                {isAuthenticated &&
-                  user.role === "chairman" &&
-                  entry.id !== currentId && (
-                    <div className="mt-4">
-                      <Button
-                        onClick={() => setEntryToActivate(entry)}
-                        color="grey-125"
-                        className="text-xs"
-                      >
-                        Aktivovat tento bod programu
-                      </Button>
-                    </div>
+                  <p className="ml-auto md:ml-0 head-heavy-xs md:head-heavy-xs md:text-grey-200 whitespace-no-wrap">
+                    {format(entry.expectedStartAt, "d. M. Y")}
+                  </p>
+                </div>
+                <div className="flex-grow w-full">
+                  <h2 className="head-heavy-xs md:head-heavy-base mb-1">
+                    {isCurrent && <Link to="/">{fullTitle}</Link>}
+                    {!isCurrent && fullTitle}
+                  </h2>
+                  <div className="flex space-x-2">
+                    <strong>Navrhovatel:</strong>
+                    <span>{entry.proposer}</span>
+                  </div>
+                  {entry.description && (
+                    <p className="mt-2 leading-tight max-w-3xl">
+                      {entry.description}
+                    </p>
                   )}
+                  {isAuthenticated &&
+                    user.role === "chairman" &&
+                    entry.id !== currentId && (
+                      <div className="mt-4">
+                        <Button
+                          onClick={() => setEntryToActivate(entry)}
+                          color="grey-125"
+                          className="text-xs"
+                        >
+                          Aktivovat tento bod programu
+                        </Button>
+                      </div>
+                    )}
+                </div>
               </div>
-            </div>
-          );
-        })}
-      </div>
-      <ModalConfirm
-        isOpen={!!entryToActivate}
-        onConfirm={onActivateConfirm}
-        onCancel={onActivateCancel}
-        confirming={activating}
-        error={activationError}
-        title="Aktivovat bod programu?"
-        yesActionLabel="Aktivovat"
-      >
-        PogramovanĂ˝ bod{" "}
-        <strong>{entryToActivate && entryToActivate.title}</strong> bude
-        aktivován. Chcete pokračovat?
-      </ModalConfirm>
-    </article>
+            );
+          })}
+        </div>
+        <ModalConfirm
+          isOpen={!!entryToActivate}
+          onConfirm={onActivateConfirm}
+          onCancel={onActivateCancel}
+          confirming={activating}
+          error={activationError}
+          title="Aktivovat bod programu?"
+          yesActionLabel="Aktivovat"
+        >
+          PogramovanĂ˝ bod{" "}
+          <strong>{entryToActivate && entryToActivate.title}</strong> bude
+          aktivován. Chcete pokračovat?
+        </ModalConfirm>
+      </article>
+    </>
   );
 };
 
diff --git a/src/pages/Protocol.jsx b/src/pages/Protocol.jsx
index 35709933cd8945441ca8448d8539d857b9c9f8d9..9b51c4ea2cbc3c18b54696f7f0047b84ad590382 100644
--- a/src/pages/Protocol.jsx
+++ b/src/pages/Protocol.jsx
@@ -1,4 +1,5 @@
 import React, { useCallback, useState } from "react";
+import { Helmet } from "react-helmet";
 import useInterval from "@rooks/use-interval";
 
 import { loadProtocol } from "actions/global-info";
@@ -54,56 +55,73 @@ const Protocol = () => {
   };
 
   return (
-    <article className="container container--default py-8 lg:py-24">
-      <h1 className="head-alt-md lg:head-alt-lg mb-8">Zápis z jednání</h1>
+    <>
+      <Helmet>
+        <title>Zápis ze zasedání | CF 2021 | Pirátská strana</title>
+        <meta
+          name="description"
+          content="Interaktivní zápis z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+        <meta
+          property="og:title"
+          content="Zápis ze zasedání | CF 2021 | Pirátská strana"
+        />
+        <meta
+          property="og:description"
+          content="Interaktivní zápis z on-line zasedání Celostátního fóra České pirátské strany, 9. 1. 2021."
+        />
+      </Helmet>
+      <article className="container container--default py-8 lg:py-24">
+        <h1 className="head-alt-md lg:head-alt-lg mb-8">Zápis z jednání</h1>
 
-      <div className="flex items-start">
-        <div className="lg:w-2/3">
-          {!protocolUrl && (
-            <ErrorMessage>Zápis momentálně není k dispozici.</ErrorMessage>
-          )}
-          {protocolLoadError && (
-            <ErrorMessage>
-              Při stahování záznamu z jednání došlo k problému:{" "}
-              {protocolLoadError.toString()}
-            </ErrorMessage>
-          )}
-          {protocolUrl && <></>}
-          {htmlContent && (
-            <div
-              className="leading-tight text-sm lg:text-base content-block"
-              dangerouslySetInnerHTML={htmlContent}
-            ></div>
-          )}
-        </div>
-        <div className="hidden lg:block card elevation-10 w-1/3">
-          <div className="lg:card__body content-block">
-            <h2>Jak to funguje?</h2>
-            <p>
-              Zápis se aktualizuje automaticky každých 10 sekund. Pokud chceš
-              aktualizaci vynutit ručně, můžeš využít tlačítko níže.
-            </p>
-            <Button
-              icon="ico--refresh"
-              loading={protocolLoading}
-              className="btn--fullwidth"
-              onClick={forceLoad}
-              color="black"
-              bodyProps={{
-                style: {
-                  position: "relative",
-                },
-              }}
-            >
-              <span style={progressStyle}></span>
-              <span style={{ position: "relative" }}>
-                {protocolLoading ? "Aktualizace..." : "Aktualizovat"}
-              </span>
-            </Button>
+        <div className="flex items-start">
+          <div className="lg:w-2/3">
+            {!protocolUrl && (
+              <ErrorMessage>Zápis momentálně není k dispozici.</ErrorMessage>
+            )}
+            {protocolLoadError && (
+              <ErrorMessage>
+                Při stahování záznamu z jednání došlo k problému:{" "}
+                {protocolLoadError.toString()}
+              </ErrorMessage>
+            )}
+            {protocolUrl && <></>}
+            {htmlContent && (
+              <div
+                className="leading-tight text-sm lg:text-base content-block"
+                dangerouslySetInnerHTML={htmlContent}
+              ></div>
+            )}
+          </div>
+          <div className="hidden lg:block card elevation-10 w-1/3">
+            <div className="lg:card__body content-block">
+              <h2>Jak to funguje?</h2>
+              <p>
+                Zápis se aktualizuje automaticky každých 10 sekund. Pokud chceš
+                aktualizaci vynutit ručně, můžeš využít tlačítko níže.
+              </p>
+              <Button
+                icon="ico--refresh"
+                loading={protocolLoading}
+                className="btn--fullwidth"
+                onClick={forceLoad}
+                color="black"
+                bodyProps={{
+                  style: {
+                    position: "relative",
+                  },
+                }}
+              >
+                <span style={progressStyle}></span>
+                <span style={{ position: "relative" }}>
+                  {protocolLoading ? "Aktualizace..." : "Aktualizovat"}
+                </span>
+              </Button>
+            </div>
           </div>
         </div>
-      </div>
-    </article>
+      </article>
+    </>
   );
 };